There's a question that comes up the moment a team outgrows a single uptime check: we already collect real user data, so why would we also pay a robot to visit our own site?
It's a fair question, and the usual answer — "you need both!" — is useless without saying why. The two approaches don't measure the same thing badly. They measure genuinely different things, and each one is blind in a way the other is not.
The short version:
- Real user monitoring (RUM) is passive. It instruments your actual application and reports what your actual visitors experienced, on their actual devices and networks.
- Synthetic monitoring is active. It runs a scripted check from infrastructure you control, on a schedule, whether or not anyone is using the service.
RUM tells you what happened. Synthetic tells you what would happen right now. Those are different questions, and the gap between them is where most outages live.
Side by side
| Real user monitoring | Synthetic monitoring | |
|---|---|---|
| Data source | Real visitor sessions | Scripted checks from probe nodes |
| Method | Passive — instruments the app | Active — simulates a user |
| Needs traffic? | Yes. No visitors, no data | No. Runs on a schedule regardless |
| Coverage | Only paths users happen to take | Only paths you scripted |
| Detects an outage | When users hit it (and only if enough do) | Within one check interval |
| Pre-production use | No — needs real users | Yes — staging, canary, pre-launch |
| Baseline stability | Noisy; varies with device, network, geography | Stable; same script, same node, same conditions |
| Answers | "What did our customers experience?" | "Is the service working right now?" |
| Typical blind spot | Low-traffic pages, off-hours, first user to hit a bug | Anything you didn't think to script |
| Implementation | JS snippet or SDK in your app | External checks, no code changes |
Where RUM is blind
RUM's fundamental constraint is that it is a sampling method with no control over the sample. You measure whoever showed up.
No traffic means no signal. Your checkout flow breaks at 03:00. Nobody buys anything at 03:00. RUM records nothing unusual because nothing happened — and the outage runs until the first customer of the morning hits it and (maybe) complains. This is the single most common reason teams add synthetic checks: RUM's detection time is a function of your traffic pattern, not your incident.
Total outages produce silence, not alerts. If your app fails to load at all — DNS failure, expired certificate, server refusing connections — the RUM script never executes, because the RUM script lives inside the page that isn't loading. A hard outage looks like a traffic drop, which is indistinguishable from a quiet Sunday until you correlate it against something else. RUM is instrumentation inside the thing being measured, and that's a structural weakness.
Attribution is genuinely hard. A user in a rural area on a saturated mobile connection reports a 9-second load. Is that your server, your CDN, their ISP, or their phone? RUM's variance is dominated by conditions you don't control, which makes it excellent for understanding experience and poor for detecting regressions. A 200 ms server-side slowdown disappears into the noise.
Nothing pre-production. You cannot RUM a staging environment that has no users, which means RUM can never catch a regression before you ship it.
Where synthetic is blind
Synthetic monitoring has the opposite shape: total control over the measurement, and no connection to reality.
You only test what you scripted. A synthetic check covering your homepage, login, and checkout will pass with complete confidence while the account settings page throws a 500 for every user. Coverage is a deliberate act, and coverage gaps are invisible by definition — the check that doesn't exist never fails.
A clean synthetic result is not a claim about your users. Your probe node sits in a data centre on a fast, stable connection running a headless browser with an empty cache. It measures a scenario almost none of your customers are in. Synthetic numbers are useful as a baseline to compare against themselves over time, not as an estimate of real-world experience. Treating your synthetic p95 as your users' p95 will make you confidently wrong.
Scripts rot. Every UI change is a chance for a selector to break. The failure mode is nasty in both directions: a broken script that fails constantly gets muted and stops being monitoring at all, and a broken script that silently passes — because it's asserting on an element that always renders — is worse than no check.
Third-party and personalised content is awkward. Logged-in states, A/B tests, geo-targeted content, and consent banners all need explicit handling or your check tests a page no real user ever sees.
The detection gap
Here's the practical framing. Both methods eventually notice a serious outage. What differs is when, and that difference is what you're actually buying.
Synthetic detection time is bounded by your check interval. A 60-second check means you know within 60 seconds, at 04:00 on a holiday, with zero users affected.
RUM detection time is bounded by traffic volume and your alerting thresholds. You need enough failed sessions to clear statistical noise. On a high-traffic page, that might be seconds. On a page that gets 40 visits a day, it might be hours — and every one of those sessions is a real customer having a bad time.
This maps directly onto MTTD, which drives MTTR. Time you spend not knowing is time added to every incident. If you're running an error budget, slow detection burns it just as fast as slow repair.
The corollary matters too: synthetic checks generate evidence. An external, timestamped, independent record of availability is what you need to report against an SLA or drive a status page. "Our internal telemetry says we were fine" is a weak position in a customer dispute. A third-party probe log is not.
Synthetic vs passive monitoring — the same distinction, older words
"Passive monitoring" is the umbrella term for anything that observes traffic that was going to happen anyway: RUM, server access logs, network taps, APM traces. "Active" or "proactive" monitoring generates its own traffic. RUM is one kind of passive monitoring — the client-side kind.
So if you're comparing synthetic vs passive monitoring, it's the same axis as RUM vs synthetic, just drawn wider. The trade-off doesn't change: passive methods are truthful but dependent on traffic; active methods are always-on but only as good as their coverage.
Worth separating out one neighbour: application performance monitoring (APM) is also passive, but it instruments the server side — traces, spans, database queries, function timings. RUM tells you the page took 6 seconds. APM tells you 4.2 of those seconds were one unindexed query. Synthetic tells you it's still taking 6 seconds at 3 a.m. Three different questions.
How to decide
Start with synthetic if you need to know the service is up, you have low or spiky traffic, you're accountable to an SLA, you want alerts before customers notice, or you have no ability to add client-side instrumentation. It's also the only option that works with no code changes — an uptime check, a DNS check, or an API check can be running in minutes.
Add RUM when your availability problem is solved and your next question is about experience: which real-world segments are slow, whether Core Web Vitals are hurting your search ranking, how performance actually differs by device and region, and which slow pages correlate with drop-off.
The order matters. Availability is a floor; experience is an optimisation on top of it. Teams that buy a sophisticated RUM product before they have reliable outage detection routinely discover their first major incident from a customer email.
A reasonable starting shape for a small team: synthetic uptime checks on every public endpoint at 60-second intervals from at least two geographic regions, scripted transaction checks on your two or three revenue-critical flows, certificate expiry monitoring, and alerts routed to a channel someone actually watches. That's your floor. RUM comes after, when you want to know not whether it worked, but how well.
Two regions is not padding — a single probe cannot distinguish "the service is down" from "the path between this one node and your service is down." Requiring agreement from two nodes before alerting is the cheapest false-positive filter available, and false positives are how alert fatigue starts.
Frequently asked questions
Is RUM better than synthetic monitoring? Neither is better; they answer different questions. RUM measures what real visitors experienced but needs traffic and goes silent during a total outage. Synthetic measures availability and performance on a fixed schedule but only covers scripted paths. Most teams run synthetic for detection and RUM for experience analysis.
Can synthetic monitoring replace real user monitoring? For availability and SLA reporting, yes. For understanding how your application performs across real devices, networks, and geographies, no — synthetic runs from a data centre under conditions almost no customer shares.
Why doesn't RUM catch downtime? RUM instrumentation runs inside your application. If the page, DNS, or TLS handshake fails, the script never executes and reports nothing. The outage appears as an absence of data rather than an error, which is hard to alert on reliably.
What's the difference between synthetic and passive monitoring? Passive monitoring observes traffic that already exists (RUM, logs, APM traces). Synthetic — also called active or proactive monitoring — generates its own traffic on a schedule. Passive is truthful but traffic-dependent; active is always-on but limited to what you scripted.
How often should synthetic checks run? Every 60 seconds for critical public endpoints. The interval is your detection floor: a 5-minute interval means a 5-minute outage can pass entirely unrecorded, which matters if you report uptime against an SLA.
Does synthetic monitoring need code changes? No. Checks run from external probe nodes against your public endpoints. RUM requires adding a JavaScript snippet or SDK to your application.
Where to start
If you don't yet have an external availability monitoring, that's the gap worth closing first — it's the one that costs you customers rather than conversion percentage points.
Xitoring runs synthetic checks — HTTP/HTTPS, API, DNS, ping, TCP/UDP, SMTP, and scripted flows — from global probing nodes, with certificate expiry monitoring, public status pages, and alerts across more than 15 notification channels.
Start monitoring free and get your detection time down to a minute.
