Finding and fixing a bottleneck — the practical framework I wrote about earlier — answers “why is this slow.” SLOs answer a different question: how much slow, or how much down, is actually acceptable, as an explicit number instead of a feeling. “We aim for high availability” isn’t a number, and it can’t be argued with — which is exactly the problem it causes. An SLO turns that vague aspiration into an actual number with actual consequences, and the error budget that falls out of it is the part that changes team behavior, not just the reporting.
Three Terms That Get Used Interchangeably and Shouldn’t Be
An SLI (Service Level Indicator) is a directly measured value — “percentage of requests completed in under 300ms,” “percentage of requests that returned a non-5xx status.” An SLO (Service Level Objective) is the internal target for that indicator — “99.9% of requests under 300ms, measured over a rolling 30 days.” An SLA (Service Level Agreement) is the SLO’s externally-facing, contractual cousin, usually set looser than the internal SLO on purpose, with a financial or contractual consequence attached for missing it. The distinction that actually matters day to day: an SLO is a target you manage against internally; an SLA is a promise with a penalty, and the gap between the two numbers is the margin you’re not supposed to spend accidentally.
99.9% Doesn’t Mean What It Feels Like It Means
A target expressed as a percentage hides the actual number of minutes it permits, and the hidden number is usually far more revealing:
99.9% = 43 minutes, 50 seconds of downtime allowed per month
99.95% = 21 minutes, 54 seconds
99.99% = 4 minutes, 23 seconds
99.999% = 26 secondsEach additional nine isn’t a small improvement — it’s roughly a 10x reduction in the operational tolerance for anything going wrong, and a 10x increase in what it typically costs to achieve (multi-region failover, active-active databases, extensive automated remediation with no human in the loop). Picking a target should start from “what actually justifies this cost for this specific service” — an internal admin dashboard three people use has no business targeting the same 99.99% as a payment API, and pretending otherwise just means engineering effort gets spent chasing a number the business impact never justified.
The Error Budget: What the SLO Actually Buys You Permission to Do
This is the part that changes behavior rather than just measuring it. If the SLO is 99.9% over 30 days, the error budget is the remaining 0.1% — 43 minutes and 50 seconds this month that’s allowed to be spent on things that carry risk: shipping a feature that might introduce a bug, running a risky migration, deploying more aggressively without a full staged rollout. Spend the whole budget on an outage early in the month, and the team has an explicit, numeric answer to “should we ship this risky change right now” — no, until the budget resets, because there’s a real, measured amount of failure tolerance left and it’s already gone.
What actually breaks in most organizations that adopt SLOs without the budget half of the idea: they track the percentage against the target as a dashboard number, but nothing changes when the budget’s exhausted — no freeze on risky deploys, no explicit reprioritization toward reliability work. At that point it’s a vanity metric, not the operational tool it’s designed to be. The budget is the entire mechanism; the percentage on its own is just a report.
What Actually Counts as “Bad,” and Why That Decision Is Harder Than It Looks
The obvious failure — a 500 response — is the easy case. The genuinely hard design decision in defining an SLI is everything that’s slow instead of outright broken: a request that returns 200 but took 8 seconds has, from a user’s perspective, failed just as thoroughly as one that returned an error, and a naive “percentage of non-5xx responses” SLI completely misses it. This is why most real SLIs combine both dimensions explicitly — “percentage of requests that returned successfully and completed within N milliseconds” — rather than measuring availability and latency as two unrelated numbers that can each look fine in isolation while the actual user experience is bad.
Multi-Window Alerting: The Fix for the Obvious Alerting Trap
The naive way to alert on an error budget — “page when the 30-day burn rate exceeds the SLO” — has an obvious failure mode: by the time a slow, chronic problem has actually burned through a meaningful fraction of a 30-day budget, it’s been silently degrading service for days before anyone got paged. The fix Google’s SRE practice popularized is checking burn rate across multiple time windows simultaneously — a fast one (1 hour) to catch a severe, sudden outage quickly, and a slower one (6 hours) to catch a milder but sustained degradation that a 1-hour window alone wouldn’t flag as urgent:
# simplified multi-window burn-rate alert (Prometheus-style)
- alert: ErrorBudgetBurnFast
expr: burn_rate_1h > 14.4 # would exhaust 30-day budget in ~2 days if sustained
for: 5m
- alert: ErrorBudgetBurnSlow
expr: burn_rate_6h > 6 # would exhaust it in ~5 days if sustained
for: 30mBoth windows watch the same underlying SLI; they differ only in how much sustained badness they require before firing, which is what lets one alerting rule catch both “everything just fell over” and “something’s been quietly wrong since this morning” without either drowning the team in noise from brief blips or missing a slow-burning problem entirely.
The Checklist
- Pick the target from the actual business impact of the service, not from copying whatever number sounds appropriately serious — each additional nine costs roughly 10x more to achieve.
- Define the SLI to capture both failure and unacceptable slowness — a fast wrong answer and a slow correct one can both be a bad outcome the SLI needs to catch.
- Treat the error budget as a real gate on risky work, not a dashboard number — if nothing changes when it’s exhausted, the SLO isn’t actually doing its job.
- Alert on burn rate across multiple time windows — a single 30-day check catches severe outages days too late and slow degradations not at all.
