Alerting on distributions, not single runs

Lesson 2 of 5 in Observability in Production: Watching Agents at Scale.

The first alert every team writes is “page me when a run fails.” It works for a week. Then it pages at 3 a.m. because one model call timed out, the agent retried, and the run succeeded anyway.

Non-determinism is not a bug you can alert your way out of. A single bad run is a sample, and a healthy agent produces bad samples on purpose — that is what a 94% success rate means. The alertable object is not the run, it is the distribution: a rate over a window, a percentile, a shape.

Five alert shapes cover almost everything worth waking up for.

Rate breach — success rate, tool error rate or guardrail-trip rate crosses a threshold over a window with a minimum sample count. Percentile shift — p95 or p99 latency moves beyond a band relative to the trailing week, not an absolute number you will be re-tuning forever. Budget burn rate — spend per hour projected against the daily or monthly cap, because an agent loop can consume a month of budget in an afternoon and a “monthly spend” alert arrives after the money is gone. Novel signal — a tool that has never errored starts erroring, a guardrail that has never tripped trips, an error string nobody has seen appears; novelty beats magnitude as an early indicator. Ceiling hits — the count of runs terminated by the turn limit rather than by their own stopping condition, which is the cleanest single number for “agents are thrashing.”

What each severity tier is actually for

  1. Page a human now — irreversible harm is accumulating

    Reserve the pager for signals where every further minute costs something you cannot undo: an agent writing to production, spend burning at 20× baseline, a guardrail-trip rate spike that suggests an active prompt injection campaign, or a kill switch that needs a human hand. The bar is not “important” — it is irreversible and accumulating.

  2. Open a ticket automatically — real regression, business hours

    A genuine, bounded regression: success rate down five points on one cohort, p99 up 40%, one tool’s error rate tripled. It needs an owner and a due date, not a woken engineer. Auto-file it with the cohort filter and three exemplar trace links attached, because the first ten minutes of any investigation is finding those.

  3. Land in a digest a human reads — drift, slow trends, sampled judgments

    Weekly judge scores on sampled traffic, intervention and approval-rate trends, new failure clusters, cost per successful task. Nothing here is urgent, all of it is how you notice slow decay. A digest only counts as oversight if someone is scheduled to read it.

  4. Live on a dashboard only — context for an investigation in progress

    Charts you look at because something else fired: token mix by model, retrieval hit rates, per-tenant volume. Useful, not alertable. If you cannot name the action a chart would trigger, it belongs here — or nowhere.

Should this signal page someone?

Interactive decision tree — outcomes:

  • Page it

    Population signal, accumulating irreversible harm, a documented ten-minute action, and a backtested low false-positive rate. That is the entire qualifying set — and it should stay small enough to list on one page of a runbook.

  • Auto-ticket, do not page

    A real regression that keeps until morning. Attach the cohort filter and exemplar traces to the ticket so the investigation starts from evidence. Paging on quality regressions is the fastest route to a team that ignores the pager.

  • Do not alert on one run

    Single-run alerts on a non-deterministic system are a noise generator: retries succeed, one timeout means nothing, and the pager teaches people to dismiss it. Convert it to a rate over a window — or, if this run class genuinely must never happen (a write outside the allowlist, a blocked egress attempt), the correct control is a runtime block plus a security event, not a performance alert.

  • Backtest before you arm it

    Replay the rule over the last month of history and count the firings. An untested threshold is how alert fatigue starts, and alert fatigue is a safety failure: it is the mechanism by which the one real page gets swiped away. Add a minimum-sample floor and a trailing baseline, then re-run.

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.