DEV Community

Cover image for There's no standard status page, and other lessons from tracking 96 providers
Kerolos Atallah
Kerolos Atallah

Posted on

There's no standard status page, and other lessons from tracking 96 providers

Your Slack won't load. Is it you, your VPN, the office wifi, or Slack? You open Slack's status page and it's green. It's often green while you're clearly down, because a company updates its own status page after it confirms an incident — not the moment you feel it.

I spent the last few months building OutageDeck, which reads the official status source of 96 cloud and SaaS providers and folds them into one place. I assumed the hard part would be the frontend. It wasn't. The hard part was that "official status" is a swamp. Here's what I found in it.

The short version:

  • There is no standard status format. Statuspage is common, but the tail is bespoke — Google, Slack, Heroku, Azure over RSS, and AWS in UTF-16.
  • Providers' own timestamps lag, sometimes by days, so you can't compute uptime from them.
  • Some official feeds are stale fossils, or model thousands of instances, so "is it up?" has no single answer.
  • Official status is authoritative but late — which is the whole reason crowd-sourced "is it down?" sites exist.
  • All of this pushed me toward a deliberately tiny backend: one Next.js app and a Postgres database, no queue, about $55/month.

There is no standard

Atlassian Statuspage is the closest thing to a common language. Around 89 of my 96 providers expose a Statuspage-style summary.json and incidents.json, and one adapter reads all of them. Some providers don't even run Statuspage but copy its shape anyway — incident.io serves a Statuspage-compatible endpoint on each customer's own domain, so Notion and Linear parse with the exact same code.

Then the long tail starts. Google publishes an incidents.json in its own format (shared across Cloud, Workspace, and Firebase). Slack has a bespoke API. Heroku is on the fourth version of its own. Azure only offers RSS. AWS ships an event feed encoded in UTF-16 with a byte-order mark, which silently breaks any parser that assumes UTF-8. "Just read the status page" turned into six adapters and a pile of encoding checks.

The timestamps lie

My first uptime numbers were nonsense, and it took me a while to see why: I was computing them from each provider's own captured_at timestamp, and those lag. One provider's was days behind at one point. If a feed says a state was "captured three days ago," you can't tell whether the service was down for three days or the timestamp is just stale.

The fix was to stop trusting upstream time entirely. Every observation is stamped with my check time, and uptime is computed from when I saw a state, not when the provider says it happened. The corollary matters too: if my own poller has a gap — a deploy, say — I don't backfill it as "up." Any gap longer than 30 minutes is recorded as no data, because inventing green is worse than admitting I wasn't looking.

Some official sources are fossils

A few providers technically have a machine-readable status endpoint that you still can't use. Stripe's legacy status JSON has been effectively frozen since 2024; it will cheerfully report that everything is fine, forever. Salesforce's status API models nearly 3,900 separate instances, so "is Salesforce up?" depends entirely on which pod your org sits on.

For sources like these, the honest move is to not ship them until I have something I'd trust myself. That's why they're still missing from the list. I'd rather explain a gap than fake a green light.

What the feeds did to the backend

Two properties of these feeds shaped the whole system.

They re-send their full recent history on every poll, and an unchanged upstream just re-stamps the same row. So the raw data can't reconstruct history — you can't diff yesterday back out of it. Instead of trying to rederive it later, I roll each poll's observations into daily per-provider buckets at write time. I also skip writing rows that didn't change; an early version rewrote identical rows every run and burned the database's IO budget for nothing.

I run two schedulers on purpose: a 10-minute cron as the primary, and a 30-minute job as a backstop. So runs overlap. Rather than add a queue or a lock service, I let Postgres be the referee. Alert deliveries are claimed with a unique constraint before anything goes out:

-- alert_deliveries has: unique (subscription_id, event_key)
insert into alert_deliveries (subscription_id, event_key, payload)
values ($1, $2, $3)
on conflict (subscription_id, event_key) do nothing;
-- 1 row inserted  -> I won the claim, send the alert
-- 0 rows inserted -> another run already has it, skip
Enter fullscreen mode Exit fullscreen mode

The insert that survives the unique index is the one that sends; the overlapping run writes nothing and moves on. No queue, no exactly-once framework, no dead-letter topic. The uptime writes take a per-entity advisory lock for the same reason. The whole thing is one Next.js app and a Postgres database, no background workers, running on about $55 a month.

So I built the thing I wanted

OutageDeck is the result: one place to check whether 96 major providers are up, sourced from each one's official status feed rather than from user complaints. It's free to use and there's no signup to check a provider. Under the hood it's the pipeline above — official-only, honest about timestamps, and clear when it just doesn't know yet.

If you want more than a webpage, there's a public JSON API, embeddable SVG status badges you can drop in a README, RSS feeds per provider, and an OpenAPI 3.1 doc.

Two honest caveats: incident history only goes as deep as each upstream feed exposes, so this isn't a system of record for ancient outages; and I'm still adding providers as I find sources I actually trust.

Try it, and stay in the loop

  • Check any provider, free, no signup: outagedeck.com
  • Want a heads-up when something breaks? Free email alerts for up to 5 providers; paid plans add Slack, Discord, and webhooks.
  • Prefer a digest? I send a short weekly rundown, This week in cloud outages — you can subscribe on the site.

I'd genuinely like to know two things in the comments: which providers you'd want tracked next, and what would make the API useful inside your own monitoring. I'll be writing up more of the internals (the uptime rollups, the fail-open API) — follow along if that's your thing.

Top comments (0)