Synthetic Monitoring: Proving the Path Still Works
There is a specific kind of incident that infrastructure monitoring is structurally incapable of catching. Every host responds, every port is open, every certificate is valid, every status code is 200 — and nobody can log in, because a session store is unreachable and the login handler is returning a rendered error page with a perfectly healthy status. The dashboard is green and the product is down. Synthetic monitoring exists for that gap: instead of asking each component whether it feels well, it performs the sequence a user performs and checks that it completed.
Why component health does not sum to service health
Component monitoring makes an assumption that is usually true and occasionally catastrophic: that if every part is healthy, the whole is working. What it actually verifies is that each part responds when asked about itself. It cannot verify the interactions, and the interactions are where the interesting failures live — a service that is up but returning malformed responses to one consumer, an authentication dependency that times out only under a particular code path, a database connection pool exhausted by one endpoint while every health check sails through on a reserved connection.
The pattern to internalise is that health checks are usually designed to be cheap, which means they are designed to avoid the expensive paths — the ones that touch the database, call the third party, or exercise the session store. Those are precisely the paths that fail. A health endpoint that returns 200 without touching anything real is a check that the process is running, which is worth having and is not the same claim.
What running the whole path proves
A synthetic check exercises the path in one browser session, which means state carries between steps. That is the property that makes it possible to verify anything behind a login, and it is why a sequence of independent requests is not a substitute: authentication, session handling, redirect chains and client-side rendering all participate in the outcome, and all of them are skipped by a request that fetches a URL and stops.
For an operator the highest-value flows are usually not the obvious ones. Login and checkout get monitored because they are visible. The flows that actually surprise people are the rarely exercised ones — password reset, email verification, a failover path, an admin function used once a quarter — because they break silently after an infrastructure change and are not discovered until the day somebody urgently needs them.
Where it fits against the rest of your monitoring
Synthetic checks are not a replacement for availability monitoring; they are a layer above it that answers a different question. Availability checks are cheap enough to run every minute against every endpoint, which makes them the right tool for the most common failure — something is simply down. Synthetic checks are more expensive and run against a handful of journeys, which makes them the right tool for the most costly failure — everything is up and the thing that makes money does not work.
A reasonable arrangement is broad, frequent availability checking across everything, plus a small number of synthetic flows covering the paths where failure is expensive or discovery would otherwise be slow. Trying to monitor every journey synthetically produces a maintenance burden that eventually gets abandoned, which is worse than monitoring three journeys well.
The honest trade-off
Synthetic checks are more brittle than infrastructure checks, and it is better to know that going in. They are written against a user interface, and user interfaces change: a redesigned login form breaks a flow that was written against the old markup, and the check fails while the site works perfectly. That is a false alarm, and enough of them will train a team to ignore the alert — which is the failure mode that matters, because an ignored check is worse than no check.
The mitigation is to write steps against the most stable selectors available and to treat a synthetic check as something that gets updated alongside the interface it exercises, rather than as configuration that is set once. A flow that nobody maintains will eventually be producing noise, and the day it produces real signal is the day everyone assumes it is noise again.
What a failed run should tell you
The difference between a useful synthetic check and an irritating one is what arrives when it fails. A pass/fail result means the investigation starts from nothing and the first task is reproduction, which is the slowest part. A result that names the failing step, captures the browser at that moment, and retains the full request waterfall from the run means the diagnosis frequently does not require reproduction at all — particularly valuable for a failure at 3am that will have resolved itself by the time anyone is awake to look.