Multi-Environment Monitoring: Staging vs Production
Set up synthetic monitoring across staging, production, and preview deployments. Learn environment variable patterns, frequency strategies, and CI/CD integration.
Monitoring shouldn't start in production. By running synthetic checks against staging, preview, and production environments, you catch bugs at every stage of your development lifecycle.
Why Monitor Multiple Environments?
| Environment | Purpose | What It Catches |
|---|---|---|
| Staging | Pre-production validation | Regressions before they reach users |
| Preview/PR | Per-branch testing | Feature-specific breakage |
| Production | Live user experience | Real-world availability issues |
Strategy Overview
Environment-Specific Configuration
Use environment variables to point the same Playwright script at different environments:
import { test, expect } from "@playwright/test";
const BASE_URL = process.env.MONITOR_BASE_URL || "https://app.example.com";
test("login flow works", async ({ page }) => {
await page.goto(`${BASE_URL}/login`);
await page.getByLabel("Email").fill(process.env.TEST_USER_EMAIL!);
await page.getByLabel("Password").fill(process.env.TEST_USER_PASSWORD!);
await page.getByRole("button", { name: "Sign In" }).click();
await expect(page.getByText("Dashboard")).toBeVisible();
});Recommended Frequencies
| Environment | Frequency | Reasoning |
|---|---|---|
| Production | Every 5 min | Real users affected immediately |
| Staging | Every 15-30 min | Lower urgency, but should stay green |
| Preview | On-demand / CI trigger | Only test when there's a new deploy |
Setting Up Multi-Environment Monitoring
Option 1: Duplicate Checks with Different Variables
Create separate checks for each environment:
-
Check: Login (Production)
MONITOR_BASE_URL=https://app.example.comTEST_USER_EMAIL=prod-test@example.com- Frequency: Every 5 minutes
- Alert Policy: Critical — Page On-Call
-
Check: Login (Staging)
MONITOR_BASE_URL=https://staging.example.comTEST_USER_EMAIL=staging-test@example.com- Frequency: Every 30 minutes
- Alert Policy: Warning — Slack Only
Option 2: CI/CD-Triggered Checks
Trigger checks via API after each deployment:
# GitHub Actions example
- name: Verify Staging Deploy
run: |
curl -X POST "https://app.supaguard.com/api/checks/$STAGING_CHECK_ID/execute" \
-H "Authorization: Bearer ${{ secrets.SUPAGUARD_API_KEY }}"→ CI/CD Integration Guide for detailed setup
Alert Strategy by Environment
Not all environments deserve the same alert urgency:
| Environment | Alert Action | Channel |
|---|---|---|
| Production | Page immediately | PagerDuty + Slack #critical |
| Staging | Notify during business hours | Slack #staging-alerts |
| Preview | Log only, fail the CI build | CI/CD pipeline output |
[!TIP] For staging, consider using a separate alert policy with a longer delay (e.g., alert only after 3 consecutive failures). Staging environments are often less stable, and you don't want staging noise to desensitize your team to production alerts.
Handling Environment Differences
Different Credentials per Environment
Use separate Organization Variables with environment-specific names:
| Variable | Production | Staging |
|---|---|---|
MONITOR_BASE_URL | https://app.example.com | https://staging.example.com |
TEST_USER_EMAIL | prod-bot@example.com | staging-bot@example.com |
TEST_USER_PASSWORD | (production test password) | (staging test password) |
Test Data in Staging
Staging environments often have different data:
// Use conditional assertions for environment-specific data
const baseUrl = process.env.MONITOR_BASE_URL!;
const isProduction = baseUrl.includes("app.example.com");
if (isProduction) {
// Production has real data
await expect(page.getByTestId("item-count")).not.toHaveText("0");
} else {
// Staging might have fewer items
await expect(page.getByTestId("item-count")).toBeVisible();
}Feature Flags
If your staging environment has features not yet in production:
const hasNewDashboard = process.env.FEATURE_NEW_DASHBOARD === "true";
if (hasNewDashboard) {
await page.getByRole("tab", { name: "Analytics" }).click();
await expect(page.getByTestId("analytics-panel")).toBeVisible();
}Best Practices
- Use the same scripts — Write scripts once and parameterize with environment variables. Don't maintain separate scripts per environment
- Test staging before production — In CI/CD, run staging checks first. Only promote to production if staging passes
- Separate alert policies — Never use the same alert policy for staging and production
- Keep staging realistic — Mirror production data and configuration as closely as possible
- Clean up test data — Set up data cleanup in staging to prevent test pollution
Next Steps
- CI/CD Integration — Automate checks in your deploy pipeline
- Environment Variables — Manage per-environment credentials
- Configuring Alerts — Set up environment-specific policies
- How to Monitor a SaaS App — Broader monitoring strategy
The Monitoring as Code Tax: Why MaC is Not Enough
Monitoring as Code (MaC) promised efficiency but delivered maintenance overhead. Learn how AI-Native monitoring removes the 'Monitoring Tax' from your developers.
Global Network Path Analysis
Debug regional performance issues by analyzing the network path. Learn how supaguard helps you identify latency bottlenecks across our global network.