Skip to content
Blog

Status pages that can't lie

How RealUptime status pages stay honest: per-region checks, templated incident text, one set of numbers, and provider claims labeled as claims.

Every few months a screenshot does the rounds on developer forums: a big provider's status page, all green, next to an error page from that same provider, timestamped the same minute.

Nobody at those companies sat down and decided to lie. The lying is structural. A status page updated by hand, during an incident, by the people busiest with the incident, will drift toward green. Every minute of publicly admitted downtime has a cost, and every incentive points one way.

We build status page software, so we spent a lot of time asking which of these failure modes we can make structurally impossible, rather than merely discouraged.

Why does a status page show green during an outage?

A status page shows green during an outage because a person decides what it says, and a single probe decides what that person knows. A single-location check collapses a regional outage into a coin flip. If the probe happens to sit outside the blast radius, the page is green while a continent's worth of your users are down.

Our checks run from four named regions, and the public page renders each region's state separately. When Frankfurt is broken and Virginia is fine, the page says exactly that, because saying less would be the lie. Each of those states is defined by what the probes actually saw, not by a judgement call: see what each monitoring status means.

The page also refuses to contradict its own incident list. An open incident always outranks a green reading, so the banner never claims everything is fine while an unresolved incident is open.

When an upstream provider is the cause, the incident says so. If your responses in a region came through Cloudflare or Vercel, and that provider's own status page, such as Cloudflare's, reports the edge location for that region as degraded or under maintenance, the incident reads degraded performance and names the provider with a link. When either fact is missing, nothing changes.

Incident copy is templated, on purpose

Status updates on our pages are built from deterministic templates fed by measured state: what is failing, from where, since when. During your worst hour you are not staring at an empty text box deciding how to spin it. Nobody can soften "down" into "some users may be experiencing intermittent elevated error rates."

Templates also keep the severity honest. A failure in one of several regions reads "partial outage in Australia", not a blanket "is down". A failure in every region reads as a major outage. Those impact levels (major outage, partial outage, degraded performance) follow the convention in the Statuspage API, so they read the same way to anyone who has used another status page.

The incident text on our pages is never machine-generated. A hallucinated sentence published under your name, about your outage, is a special kind of damage. Templates fed by measurements cannot hallucinate.

One outage, one incident

One outage is one incident. When a check fails in several regions, the first region to confirm the failure opens the incident. Every later region is added to it and posted on its timeline, and subscribers are emailed once. The incident resolves only after every affected region has recovered.

The reverse rule matters just as much for honesty. An automatically detected incident that recovers in under 5 minutes, with no update from a person and no postmortem, counts as a blip. It stays out of the public incident history and out of the uptime figure, but nothing is deleted: the blip is still in your dashboard. Any incident someone opens by hand, edits, or writes a postmortem for is always shown, however short it was.

The badge and the numbers are the same numbers

The uptime percentage a page shows, the embeddable badge, the RSS feed, and the JSON that tools read all come from the same probe results. Paused monitors read as paused, never as up. There is no separate marketing copy of the data to quietly diverge from the operational copy.

Uptime itself follows a stated rule. A component's percentage is the share of the time window not spent in an incident, with a major outage counted as full downtime and a partial outage as 30% downtime. Degraded performance costs nothing, because uptime measures whether the service answered, not how fast. Overlapping incidents count once, at the worse impact.

Claims are labeled as claims

A status page can also show things we did not measure, and the label says which is which. A component that mirrors a third party your product depends on reads "Third-party, measured by RealUptime Outages", with a link to that vendor's outage page. A component that shows one piece of a provider like Cloudflare reads "Reported by Cloudflare, not measured".

If we have not read a provider's status page in the last 20 minutes, the row reads Unknown rather than keeping an old state. A stale green is the same lie as a hand-edited one, just slower.

What this costs us

Honesty as a feature has a price tag we pay in sales copy: our pages sometimes show yellow when a competitor's identical page would show green. We think that trade holds up, because a status page has exactly one job, and a status page nobody trusts is decoration.

The rest of what we think belongs on one is in status page best practices. If you are moving off Statuspage, what carries across is written down too.

Our own status runs on the same machinery, measured by the same probes, at status.realuptime.io. If we are having a bad day, that page will say so, whether we like it or not.