supaguardsupaguardDocs
Learn

Synthetic Monitoring Best Practices for 2025

15 proven best practices for synthetic monitoring. Learn test design, alerting strategies, team workflows, and scaling patterns from industry experts.

Synthetic monitoring is only as effective as how you implement it. These best practices—drawn from industry patterns and real-world experience—help you build a monitoring strategy that catches real issues without creating noise.

Test Design

1. Monitor User Journeys, Not Just Pages

Don't just check if a page loads. Simulate what users actually do:

// ❌ Shallow — only checks if the page returns HTML
test("homepage loads", async ({ page }) => {
  await page.goto("https://app.example.com");
  await expect(page).toHaveTitle(/Example/);
});

// ✅ Deep — tests a real user flow end-to-end
test("user can log in and view dashboard", async ({ page }) => {
  await page.goto("https://app.example.com/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();
  await expect(page.getByTestId("stats-panel")).toBeVisible();
});

2. One Flow Per Check

Each check should test a single user journey. This makes failures easy to diagnose:

  • ✅ "Login Flow" — one check
  • ✅ "Checkout Flow" — a separate check
  • ❌ "Login → Dashboard → Settings → Checkout" — too many things in one check

3. Use Stable Selectors

Your selectors should survive UI redesigns. Follow this priority:

PriorityTypeExample
1Role-basedgetByRole("button", { name: "Submit" })
2Test IDsgetByTestId("checkout-btn")
3LabelsgetByLabel("Email")
4TextgetByText("Get Started")
5CSSpage.click(".btn-primary")

Resilient Locators for a deeper guide

4. Keep Checks Fast

Checks should complete in under 30 seconds. Slow checks are expensive and delay detection:

  • Test one journey per check
  • Avoid unnecessary page navigations
  • Block heavy third-party scripts that don't affect functionality
  • Use waitUntil: "domcontentloaded" instead of "load" for SPAs

5. Handle Dynamic Content Gracefully

Don't assert on exact values that change between runs:

// ❌ Fragile — exact price might change
await expect(page.getByTestId("price")).toHaveText("$49.99");

// ✅ Resilient — verifies format, not exact value
await expect(page.getByTestId("price")).toContainText("$");

Alerting Strategy

6. Use Multi-Region Verification

Never alert based on a single region failure. supaguard's Smart Retries automatically verify from a different region before alerting—eliminating the majority of false alarms.

7. Match Alert Severity to Business Impact

Not every check deserves the same urgency:

Check CategoryFailure ImpactAlert Level
Login / AuthUsers locked out🔴 Page on-call immediately
Checkout / PaymentRevenue loss🔴 Page on-call immediately
Dashboard / Core featuresUX degradation🟡 Slack during business hours
Marketing pages / BlogMinimal impact🟢 Email digest

Configuring Alerts

8. Enable Recovery Notifications

Always know when an issue resolves—not just when it starts. Recovery alerts close the loop and prevent unnecessary investigation.

9. Review Alert Volume Monthly

If a check triggers more than 5 alerts per week, the check is either:

  • Too sensitive (adjust the assertion)
  • Testing something inherently unstable (reconsider the approach)
  • Catching real bugs (fix the underlying issue)

Team Workflows

10. Use Unlimited Seats

supaguard offers unlimited seats on all plans. Invite your entire engineering team—monitoring insights are most valuable when everyone can see them.

Team Collaboration

11. Create Shared Test Accounts

Create a dedicated service account for monitoring:

  • Email: synthetic-monitor@company.com
  • Exclude from marketing emails and analytics
  • Disable MFA
  • Give minimal permissions needed for monitored flows
  • Store credentials in environment variables

12. Document Your Monitoring Strategy

Maintain a runbook that answers:

  • What flows are monitored?
  • What's the expected behavior of each check?
  • Who is responsible for fixing failures in each area?
  • When should a check be updated vs. muted?

Scaling

13. Prioritize by Revenue Impact

Start with the flows that generate revenue or prevent users from accessing your product:

  1. Authentication — Can users log in?
  2. Core Value — Can users do the main thing your app does?
  3. Payments — Can users pay you?
  4. Onboarding — Can new users get started?
  5. Everything else — Marketing pages, docs, settings

14. Monitor Across Environments

Run checks against staging, preview, and production environments with different frequencies and alert policies.

Multi-Environment Monitoring

15. Integrate with Your Deployment Pipeline

Trigger checks after every deployment to catch regressions immediately:

# Post-deploy verification
- name: Run supaguard Checks
  run: |
    curl -X POST "https://app.supaguard.com/api/checks/$CHECK_ID/execute" \
      -H "Authorization: Bearer ${{ secrets.SUPAGUARD_API_KEY }}"

CI/CD Integration

Anti-Patterns to Avoid

Anti-PatternWhy It's BadBetter Approach
Testing everything in one checkHard to diagnose, slow, expensiveOne flow per check
Hardcoding credentialsSecurity risk, hard to rotateUse environment variables
Using waitForTimeout()Slow and fragileUse auto-waiting or explicit events
Alerting on every failureAlert fatigueUse multi-region verification + thresholds
Ignoring flaky checksErodes trust in monitoringFix or remove flaky checks immediately

Next Steps

On this page