Synthetic checks
Scripted journeys run on a schedule, from outside, to prove the thing users actually do still works.
A service check proves the endpoint answers. A synthetic check proves the journey works.
Those are different. A login page that returns 200 with a broken form is up by
every measure except the one that matters.
Creating one
Monitor → Synthetic → New check. A check is a sequence of steps: navigate, fill, click, assert. Each step has a timeout and an assertion.
| Field | Notes |
|---|---|
| Name | The journey, not the URL — "checkout as a returning customer" |
| Steps | Ordered, each with an assertion |
| Interval | Minutes. These cost more than an HTTP check |
| Locations | Where it runs from |
| Severity | On failure |
What is recorded
Every run records per-step timing, the final result, and — on failure — which step failed and why.
Per-step timing is what makes a synthetic check diagnostic rather than merely binary: "checkout takes 9 seconds" is a report; "the payment step takes 8.4 of those 9 seconds" is a lead.
Alerting
A failed run raises an alert with the failing step named. The usual
For / Recovery settings apply — a single failed run on a six-step journey is
often a flaky selector rather than an outage, so For: 2 is a reasonable
default for anything with a browser in it.
Give a synthetic check a longer For than an HTTP check. A browser journey
has more ways to fail transiently and each false page costs more attention
than the check saves.
Keeping them honest
Synthetic checks rot: a selector changes, a test account expires, a consent banner appears. A check that has been failing for a week with nobody acting on it is worse than no check, because it trains people to dismiss that alert.
Alert intelligence will show you which ones those are.
What they are not
Not load testing, and not a replacement for real-user monitoring. A synthetic check tells you the journey works from one place with one account. RUM tells you what actual users experienced.
Where this behaviour lives: backend/internal/worker/synthetic_worker.go, frontend/src/app/synthetic/. If the code and this page disagree, the code is right — please fix the page.
Part of Monitor — Everything that watches something and reports what it saw.