tech, developers, and the code underneath

issue 112· essay·

Your monitoring is measuring the wrong nines

Availability percentages are a compliance artifact. Here's what to measure if you want to know whether users are having a bad time.

Your dashboard says 99.95% availability. Your support queue says otherwise. Both are correct, and the dashboard is measuring something that does not matter.

what "available" usually means#

For most teams it means: a health check endpoint returned 200 within a timeout, from a monitoring location, on a schedule.

That measures whether a process is running. It does not measure whether anyone can do anything.

Real user-visible failures that a health check will not catch:

  • The API returns 200 with an empty result set because a downstream cache is cold.
  • Requests succeed at p50 and take 30 seconds at p95, and the p95 is entirely one large customer.
  • Login works, but only for users whose sessions were created before the deploy.
  • Everything works except in one region, which is 8% of traffic and 40% of revenue.
  • Writes succeed and are silently not persisted because a queue consumer is wedged.

Every one of those is a full outage for the affected users and none of them move a health-check-based availability number.

what to measure instead#

Measure user journeys, not endpoints. Pick the three to five things users come to your product to do. Checkout. Send a message. Run a query. Deploy. Instrument those end to end, and define success as "the journey completed correctly," not "each service returned 200."

Measure from the client where you can. Server-side metrics cannot see DNS failures, TLS problems, CDN issues, or the user's terrible network. A meaningful fraction of real user-visible failure is invisible from inside your datacenter.

Use success rate, not uptime. The fraction of requests that succeeded, over a window. This handles partial failure correctly, which uptime does not. A service serving 60% of requests successfully is not "up," and a binary metric says it is.

Slice by everything. Aggregate metrics hide the failures that matter. The same success rate can mean "everyone has a slightly bad time" or "one tenant is completely broken," and those require completely different responses.

Slice by: customer, region, client version, endpoint, feature flag. If you cannot slice by these, that is your observability gap.

Set a latency threshold and count violations. "p99 latency" as a number is hard to alert on and easy to game. "Percentage of requests slower than 2 seconds" is a success rate, comparable across time, and directly meaningful. If more than 1% of checkouts take longer than 2 seconds, something is wrong, and you can say that in a sentence a product manager understands.

the SLO framing, without ceremony#

You do not need a formal SLO program. You need three numbers per critical journey:

  1. What fraction of attempts must succeed. 99.9%, say.
  2. What counts as success. Completed, correct, within a latency bound.
  3. Over what window. 28 days, rolling.

The difference between your target and 100% is your error budget. When you are burning it fast, stop shipping and fix reliability. When you have plenty, ship faster and take more risk.

That is the entire value of the framework: it converts "should we prioritize reliability or features" from an argument into an arithmetic question. Everything else in the SLO literature is optional.

alerting on the right thing#

Alert on symptoms, not causes. "Checkout success rate below 99%" pages someone. "CPU above 80%" does not, because high CPU is sometimes fine and low CPU with a broken service is not.

Alert on burn rate, not instantaneous values. A single failed request should not page anyone. Burning a month's error budget in an hour should page everyone. Multi-window burn-rate alerting is the single best improvement most teams can make to their paging, and it dramatically reduces false pages.

Every page should have an action. If the runbook is "look at it and see if it recovers," it is not a page. It is a dashboard.

the test#

Take your last five user-reported incidents. For each, ask: did an alert fire before the user reported it?

If the answer is mostly no, your monitoring is measuring the wrong things, and no amount of additional dashboards will fix that. The gap is not visibility. It is that you are watching the system instead of watching the users.

Dom, January 27, 2026

get README in your inbox

One dispatch, no noise. Tech and developer news, plus the occasional long piece on the craft.

subscribe →