Real user monitoring (RUM) passively records the performance real visitors experienced in their own browsers, while synthetic monitoring actively runs scripted probes against a site from controlled locations on a schedule. The trade-off is coverage versus control: RUM captures the truth about user experience, synthetic produces a repeatable signal you can alert on, and mature teams run both.
Real user monitoring vs synthetic monitoring: what's the difference?
RUM and synthetic monitoring answer different questions. RUM measures what actually happened to real users, across every browser, network, and geography that visited. Synthetic monitoring measures what a scripted client experienced under fixed conditions, so it produces a clean baseline that keeps working at 3 a.m. and before launch, when no real users exist yet.
| Question | RUM | Synthetic monitoring |
|---|---|---|
| How is data collected? | Passively, from real user sessions via a browser or mobile SDK | Actively, by scripted probes (HTTP checks, API transactions, browser journeys) on a schedule |
| Availability alerting | Weak: no traffic means no data, so a quiet-hours outage goes unseen | Strong: probes run around the clock and fail within one or two check intervals |
| SLA verification | Noisy: user device and network variance is baked into every number | Strong: a fixed client and location produce a stable, contract-grade baseline |
| Geographic coverage | Wherever users actually are, in real traffic proportions | Only the probe locations you configure |
| Pre-production testing | Not possible; RUM needs real traffic | Strong: the same scripts run against staging before launch |
| Long-tail experience | Strong: captures every device, network, and rarely-used path | Blind: scripts only test the paths someone wrote |
| Cost and data volume | Scales with traffic (events per session × sessions) | Scales with checks × frequency × locations; flat and predictable |
What is real user monitoring?
Real user monitoring is the passive collection of performance and experience telemetry from real user sessions, captured by a JavaScript or mobile SDK. It records page loads, Core Web Vitals, network timings, errors, and user journeys as they happen, then beacons those events to a collection endpoint for analysis.
The measurements come from standard browser APIs: the W3C Navigation Timing specification defines the page-load milestones, and Google's Core Web Vitals (LCP, CLS, and INP, which replaced FID as a Core Web Vital on March 12, 2024) define the experience thresholds most teams report against. OpenTelemetry's browser instrumentation is the vendor-neutral way to emit these events into a RUM collection pipeline.
What is synthetic monitoring?
Synthetic monitoring runs scripted probes (HTTP uptime checks, multi-step API transactions, and full browser journeys) against a system on a schedule from controlled locations. Because the client, script, network, and location are fixed, every result is directly comparable to the previous one, producing a clean time series for alerting and baselines.
This is what the Google SRE book calls black-box monitoring: "testing externally visible behavior as a user would see it." Simple checks validate that an endpoint returns HTTP 200 within a latency budget; browser-journey checks drive a real headless browser through login or checkout using Playwright- or Selenium-class tooling. Each check type runs on its own cadence, from per-minute uptime probes to browser journeys every 5–15 minutes, since a full page render costs far more per run than a ping.
Why does synthetic monitoring catch outages first?
Synthetic checks run whether or not anyone is using the site, so they detect failures during quiet hours and before launch. A probe firing every minute turns an outage into an alert within one or two intervals. RUM can only report a problem after enough real users have already been affected by it.
That property makes synthetic the right foundation for availability alerting and for SLA verification: an availability commitment needs a measurement that exists even at zero traffic, and a contract-grade number needs a fixed client rather than a shifting population of user devices. The same scripts also run against staging environments, so a broken checkout flow is caught in pre-production instead of by the first customer after deploy.
Why does RUM catch what synthetic monitoring misses?
RUM observes every real session, so it captures the combinations no script anticipates: a mid-range Android phone on a congested mobile network, a checkout path only 2% of users take, a third-party tag that slows a single region. Synthetic scripts test only the paths someone thought to write, from the locations someone chose.
Google's web-performance documentation draws the same line as field data versus lab data: lab results are reproducible but can't tell you what your actual population experienced. A synthetic browser check from a well-connected data center will happily report a fast site while p75 INP for real users on mobile fails the 200 ms threshold. Only field data weighted by real traffic answers "is the site fast for the users we actually have?"
When to choose synthetic monitoring
Synthetic monitoring is the right primary tool when the question is "is it up, and did we break it?" Choose it when:
- You need availability alerting that works at zero traffic: overnight, in new regions, or pre-launch.
- You report against an availability SLA and need a stable, controlled measurement baseline.
- You want regression checks on critical journeys (login, checkout, signup) in staging and production.
- Your traffic is too low for RUM percentiles to be statistically meaningful.
When to choose RUM
RUM is the right primary tool when the question is "what did users actually experience?" Choose it when:
- You optimize Core Web Vitals, which are defined as field metrics over real sessions.
- Your audience spans devices, networks, and geographies no probe fleet can represent.
- You need to find the slow long-tail paths and regions, not just confirm the happy path.
- You want experience data tied to sessions, errors, and business outcomes like conversion.
What the data looks like at rest
Both approaches emit events, but at very different volumes. Synthetic output is small and regular: one check per minute from 5 locations is 7,200 results per day per check. RUM output scales with traffic: at roughly 25–100 events per session, a site with 1 million daily sessions produces 25–100 million wide, high-cardinality events per day, one of the workload shapes discussed in the observability overview.
Analytically, both reduce to aggregations over event tables. A typical RUM question looks like this in SQL:
-- p75 LCP by country, last 24 hours
SELECT country, quantile(0.75)(lcp_ms) AS p75_lcp
FROM rum_events
WHERE event_type = 'web_vital'
AND timestamp > now() - INTERVAL 24 HOUR
GROUP BY country
ORDER BY p75_lcp DESCThe synthetic equivalent swaps the table and grouping (check name and probe location instead of country), which is exactly why storing both in one queryable place pays off.
Running RUM and synthetic data through ClickStack
ClickStack, the ClickHouse observability stack, stores both signal types as OpenTelemetry events in a columnar database built for high-cardinality aggregation. RUM events from OTel browser instrumentation and synthetic check results land in ClickHouse tables, and HyperDX, the ClickStack UI, sits on top for search, dashboards, and alerting.
That shared store closes the loop between the two approaches: when a synthetic check fails, the RUM sessions from the same window show whether real users were affected and where; when RUM shows a regional Web Vitals regression, a synthetic probe pins down whether it reproduces under controlled conditions. Percentile queries like the p75 example above run directly over raw events, so there is no pre-aggregation step deciding which questions you're allowed to ask later. To try both signal types in one SQL-queryable store, ClickStack is open source and runs locally with Docker.
Frequently asked questions
Do you need both RUM and synthetic monitoring?
Mature teams run both because each covers the other's blind spot: synthetic gives you availability alerting and pre-production checks that work at zero traffic, and RUM gives you ground truth about what real users experienced. Teams that can only fund one usually start with synthetic checks, which are cheap and useful from day one, then add RUM once traffic is high enough for percentiles to be statistically meaningful.
Is uptime monitoring the same as synthetic monitoring?
Uptime monitoring is the simplest form of synthetic monitoring: a scheduled HTTP check that verifies an endpoint responds correctly. Synthetic monitoring is the broader category, which also includes multi-step API transaction checks and full scripted browser journeys that validate complete user flows such as login or checkout.
How much data does real user monitoring generate?
RUM volume scales directly with traffic. A session typically emits roughly 25–100 events covering page views, Web Vitals, resource timings, and errors, so a site with 1 million sessions per day generates 25–100 million events daily. Sampling reduces cost but discards exactly the long-tail sessions RUM exists to capture.
Can synthetic monitoring verify SLAs on its own?
For availability SLAs, yes: a fixed probe fleet gives a stable, auditable measurement that exists even when traffic doesn't. For experience-level objectives such as Core Web Vitals or p75 page-load targets, no: those are defined over real user sessions, so verifying them requires field data from RUM.