MonitoringIntermediate

Synthetic Monitoring: What It Is and Why You Need It

Learn what synthetic monitoring is, how it differs from real user monitoring, and how to implement it for your web applications.

ObserveOne Team
9 min read

Synthetic monitoring is a proactive approach to monitoring web applications by simulating user interactions before real users encounter issues. Instead of waiting for problems to occur, synthetic monitoring continuously tests your application from multiple locations worldwide.

In this guide, we'll explore what synthetic monitoring is, how it works, and why it's essential for modern web applications.

What is Synthetic Monitoring?#

Synthetic monitoring (also called active monitoring or proactive monitoring) is the practice of using automated scripts to simulate user interactions with your web application. These scripts run on a schedule from various geographic locations, testing critical user flows and reporting on availability, performance, and functionality.

How Synthetic Monitoring Works#

  1. Script Creation: Define user journeys (e.g., login, checkout, search)
  2. Scheduled Execution: Run scripts every 1-15 minutes from multiple locations
  3. Data Collection: Record response times, errors, and screenshots
  4. Alerting: Notify teams when issues are detected
  5. Analysis: Track trends and identify performance degradation

Example Synthetic Test#

// Synthetic test for e-commerce checkout
test("checkout flow", async ({ page }) => {
// 1. Navigate to product page
await page.goto("https://example.com/products/123");
// 2. Add to cart
await page.getByTestId("add-to-cart").click();
// 3. Proceed to checkout
await page.getByTestId("checkout").click();
// 4. Fill shipping info (use env vars for secrets)
await page.getByTestId("email").fill(process.env.TEST_EMAIL ?? "");
await page.getByTestId("address").fill("123 Main St");
// 5. Complete purchase
await page.getByTestId("place-order").click();
// 6. Verify success
await expect(page.getByTestId("success-message")).toBeVisible();
});

This test runs every 5 minutes from multiple locations, alerting you immediately if any step fails.

Synthetic vs Real User Monitoring (RUM)#

Both synthetic monitoring and Real User Monitoring (RUM) are essential, but they serve different purposes:

AspectSynthetic MonitoringReal User Monitoring (RUM)
Data SourceSimulated usersActual users
CoveragePredefined scenariosAll user interactions
TimingContinuous (24/7)Only when users visit
GeographyControlled locationsWherever users are
DetectionProactive (before users)Reactive (after users affected)
CostPredictableScales with traffic
Use CaseCatch issues earlyUnderstand real user experience

When to Use Each#

Use Synthetic Monitoring for:

  • Monitoring critical user flows (login, checkout, registration)
  • Testing from specific geographic regions
  • Monitoring during low-traffic periods (nights, weekends)
  • Service-level agreement (SLA) compliance and uptime tracking
  • Third-party API monitoring

Use Real User Monitoring for:

  • Understanding actual user experience
  • Identifying performance issues in production
  • Tracking user behavior patterns
  • Measuring Core Web Vitals
  • A/B testing performance impact

Best Practice: Use both together for comprehensive monitoring.

Benefits of Synthetic Monitoring#

1. Proactive Issue Detection#

Catch problems before users do: when a synthetic check fails, you get an alert. You might fix it before anyone notices, or at least you’re investigating before the first support ticket.

2. Global Performance Visibility#

Test from multiple locations to ensure consistent performance:

{
"locations": [
"us-east-1", // New York
"eu-west-1", // Ireland
"ap-southeast-1", // Singapore
"sa-east-1" // São Paulo
]
}

Insight: Discover that your API is slow in Asia due to lack of content delivery network (CDN) coverage.

3. SLA compliance#

Track uptime and performance against SLAs:

Monthly Uptime: 99.95%
Average Response Time: 287ms
SLA Target: 99.9% uptime, <500ms response
Status: ✅ Meeting SLA

4. Baseline Performance Metrics#

Establish performance baselines to detect degradation:

Week 1: Average load time 1.2s
Week 2: Average load time 1.8s ⚠️
Alert: 50% performance degradation detected

5. Third-Party Dependency Monitoring#

Monitor external services you depend on:

// Monitor Stripe API
test("payment processing", async ({ page }) => {
const response = await page.request.post(
"https://api.stripe.com/v1/charges",
{
data: {
/* test charge */
},
},
);
expect(response.status()).toBe(200);
});

Types of Synthetic Monitoring#

1. Uptime Monitoring#

Simple HTTP (Hypertext Transfer Protocol) checks to verify availability:

{
"url": "https://example.com",
"method": "GET",
"expected_status": 200,
"interval": "1m"
}

Use case: Ensure your homepage is accessible.

2. API Monitoring#

Test API endpoints with assertions:

{
"url": "https://api.example.com/users",
"method": "GET",
"headers": { "Authorization": "Bearer token" },
"assertions": [
{ "type": "status", "value": 200 },
{ "type": "response_time", "value": "max_500ms" },
{ "type": "json_path", "path": "$.users[0].id", "exists": true }
]
}

Use case: Verify API functionality and performance.

3. Browser-Based Monitoring#

Full user flow testing with real browsers:

test("user registration", async ({ page }) => {
await page.goto("/signup");
await page.getByTestId("email").fill(process.env.TEST_EMAIL ?? "");
await page.getByTestId("password").fill(process.env.TEST_PASSWORD ?? "");
await page.getByTestId("submit").click();
await expect(page).toHaveURL("/dashboard");
});

Use case: Test complex JavaScript-heavy applications.

4. Transaction Monitoring#

Multi-step business-critical flows:

test("complete purchase", async ({ page }) => {
// Step 1: Login
await login(page);
// Step 2: Add product to cart
await addToCart(page, "product-123");
// Step 3: Checkout
await checkout(page);
// Step 4: Payment
await processPayment(page);
// Step 5: Verify order confirmation
await verifyOrderConfirmation(page);
});

Use case: Ensure end-to-end business processes work.

How to Implement Synthetic Monitoring#

Step 1: Identify Critical User Journeys#

List the most important flows in your application:

E-commerce:

  • Homepage → Product → Add to Cart → Checkout → Purchase
  • User Registration
  • Login
  • Search

SaaS Application:

  • Sign Up → Onboarding → First Action
  • Login → Dashboard Load
  • Create New Project
  • Invite Team Member

Step 2: Choose a Monitoring Tool#

For Simple Uptime Checks:

  • ObserveOne (free tier and paid tiers)
  • UptimeRobot (free)
  • Pingdom
  • StatusCake

For API Monitoring:

  • ObserveOne
  • Postman Monitors
  • Checkly

For Browser-Based Monitoring:

  • ObserveOne (Autopilot)
  • Checkly (Playwright-based, AI-assisted debugging)
  • Datadog Synthetics

Step 3: Write Your First Synthetic Test#

Example with ObserveOne:

// Autopilot input: paste a URL and an optional goal
{
"url": "https://example.com",
"goal": "Cover the main user flows like pricing, signup, and login"
}
// Autopilot generates editable Playwright like this, and a healer agent re-fixes it when the app changes
test('login flow', async ({ page }) => {
await page.goto('https://example.com/login');
await page.getByTestId('email').fill(process.env.TEST_EMAIL ?? '');
await page.getByTestId('password').fill(process.env.TEST_PASSWORD ?? '');
await page.getByTestId('submit').click();
await expect(page.getByTestId('dashboard')).toBeVisible();
});

Step 4: Configure Monitoring Locations#

Test from regions where your users are:

{
"locations": [
"us-east", // 40% of users
"eu-west", // 35% of users
"ap-south" // 25% of users
]
}

Step 5: Set Up Alerts#

Configure alerts for different severity levels:

{
"alerts": [
{
"condition": "failure",
"channels": ["slack", "pagerduty"],
"severity": "critical"
},
{
"condition": "slow_response > 2s",
"channels": ["email"],
"severity": "warning"
}
]
}

Step 6: Create Dashboards#

Visualize synthetic monitoring data:

  • Uptime %: 99.95% this month
  • Average Response Time: 287ms
  • Failed Checks: 3 (all resolved)
  • Slowest Location: Asia-Pacific (450ms avg)

Best Practices#

1. Test from Multiple Locations#

Don't rely on a single monitoring location:

// Bad: Only monitoring from one location
{ "location": "us-east" }
// Good: Monitoring from user regions
{ "locations": ["us-east", "eu-west", "ap-southeast"] }

2. Use Realistic Test Data#

Avoid using obvious test data that might be filtered:

// Bad
{ "email": "[email protected]" }
// Good
{ "email": "monitor.user.${timestamp}@example.com" }

3. Set Appropriate Check Intervals#

Balance cost and detection speed:

  • Critical flows: Every 1-5 minutes
  • Important flows: Every 10-15 minutes
  • Non-critical: Every 30-60 minutes

4. Monitor Third-Party Dependencies#

Test external services separately:

// Monitor Stripe separately from your checkout flow
test("stripe api health", async ({ page }) => {
const response = await page.request.get("https://api.stripe.com/v1/charges");
expect(response.status()).toBe(401); // Expect auth error (proves API is up)
});

5. Use Assertions, Not Just Status Codes#

Verify actual functionality:

// Bad: Only checking status
expect(response.status()).toBe(200);
// Good: Checking content
expect(response.status()).toBe(200);
expect(await response.json()).toHaveProperty("users");
expect((await response.json()).users.length).toBeGreaterThan(0);

6. Implement Retry Logic#

Avoid false positives from transient issues:

{
"retries": 2,
"retry_interval": "30s"
}

Monitor performance degradation over time:

Week 1: 1.2s average
Week 2: 1.4s average ⚠️ Trend alert
Week 3: 1.8s average 🚨 Critical

Common Pitfalls#

1. Over-Monitoring#

Problem: Running checks too frequently wastes resources.

Solution: Match check frequency to criticality:

  • Login page: Every 5 minutes
  • Blog posts: Every 30 minutes

2. Ignoring Geographic Distribution#

Problem: Only monitoring from one region.

Solution: Test from all regions where you have users.

3. Not Testing Authentication#

Problem: Only checking public pages.

Solution: Test authenticated flows:

test("authenticated dashboard", async ({ page }) => {
await login(page);
await expect(page.getByTestId("user-dashboard")).toBeVisible();
});

4. Alert Fatigue#

Problem: Too many alerts for minor issues.

Solution: Use alert thresholds:

{
"alert_after_failures": 2, // Alert after 2 consecutive failures
"alert_after_slow_responses": 3 // Alert after 3 slow responses
}

Synthetic Monitoring Tools Comparison#

ToolBrowser TestingAPI TestingMulti-LocationAI FeaturesStarting Price
ObserveOneYes (AI-powered)YesYesYes$24/month
ChecklyYes (Playwright-based)YesYesYes (AI-assisted)$7/month
DatadogYesYesYesLimited$15/test/month
PingdomYesLimitedYesNo$10/month
UptimeRobotNoYesLimitedNoFree

Conclusion#

Synthetic monitoring helps you catch issues before users do by testing critical flows from multiple locations. Start with your most important user journey and expand from there.

Use ObserveOne's free tier to generate self-healing Playwright suites for your critical flows with Autopilot in minutes.

Frequently Asked Questions

Synthetic monitoring runs a few scripted journeys continuously to confirm key flows still work and how fast they respond. Load testing pushes heavy concurrent traffic for a short window to find the breaking point. One watches everyday health, the other measures capacity under stress.

No. Synthetic checks run from external locations and hit your site like any other visitor, so they do not sit in your real users' path and do not slow normal traffic. The only load they add is the checks themselves, which is small and predictable.

They share tooling but differ in purpose. Automated tests run in CI to block bad code before release. Synthetic monitoring runs the same style of script against production on a schedule, so it catches issues caused by infrastructure, data, or third parties after deployment, not just code defects.

Pricing usually scales with how many checks you run and how often. Simple uptime-style checks are cheap or free, while browser-based flows cost more because they use more resources. Expect to pay based on check count, frequency, and the number of monitoring regions.

Ready for AI-Powered Testing?

ObserveOne monitors your selectors 24/7 and automatically heals them when websites change. Never deal with broken tests again.

Start Free Trial