SLIs, SLOs, SLAs, and Error Budgets
Three acronyms that turn “the system should be reliable” from a wish into a number you can engineer
toward — and one idea (error budgets) that reframes the whole velocity-vs-stability argument.
Prerequisites: Availability, Monitoring & Alerting
Time to read: ~18 minutes
The problem
“The system should be highly available.” Everyone agrees, and it means nothing. How available? Who
decides? What happens when we miss it? Is 99.9% enough, or do we need 99.99% (which costs 10× more)?
🚨 Without a number, reliability arguments are just opinions, and every decision — ship faster or
be more careful? — becomes a fight between the product team (wants velocity) and the ops team (wants
stability), with no shared framework to resolve it.
SLIs, SLOs, and SLAs give you the number. Error budgets give you the framework to make decisions with
it.
The three, precisely
🚨 These are constantly confused. Get them straight:
| Term |
Is |
Example |
| SLI (Indicator) |
The measurement — what you actually observe |
“99.95% of requests returned 2xx in under 300ms last month” |
| SLO (Objective) |
Your internal target — what you engineer toward |
“99.9% of requests under 300ms” |
| SLA (Agreement) |
The contractual promise with penalties |
“99.5% uptime or you get a refund” |
The relationship, and the key insight:
SLI (what happened) → measured against → SLO (your target)
↓ (looser)
SLA (customer promise, with penalties)
🚨 The SLA is always looser than the SLO, deliberately. If you promise customers 99.5% (SLA) but
target 99.9% internally (SLO), you have a buffer — you can miss your internal target and still not
breach the contract or owe refunds. Setting your SLA equal to your SLO means every internal miss is a
financial and legal event. The gap is your margin of safety.
🎙️ “The SLI is what we measure, the SLO is what we engineer toward, and the SLA is what we promise
customers — and I’d keep the SLA looser than the SLO so an internal miss doesn’t automatically become
a refund. The SLA is the least interesting number; the SLO is what actually drives engineering.”
Choosing good SLIs
An SLI should measure what users actually experience, not internal conditions.
🚨 Good SLIs are symptom-based (same principle as alerting):
| Good SLI (user-facing) |
Bad SLI (internal) |
| % of requests served successfully |
CPU utilization |
| % of requests under 300ms |
Number of servers |
| % of data durable |
Disk space |
| Freshness of data (for a pipeline) |
Queue depth |
Common SLI types:
- Availability — fraction of successful requests.
- Latency — fraction under a threshold. 🚨 Use a threshold + percentile (“99% under 300ms”),
not an average — averages hide the tail. → Performance
- Quality/correctness — fraction of correct responses (for systems that can degrade gracefully).
- Freshness — for data pipelines, how stale the data is.
- Durability — fraction of data not lost.
🚨 Measure at the point the user experiences it — ideally at the load balancer or client, not deep
inside a service. A service can report 100% success while the load balancer returns errors the service
never saw.
Setting the SLO: don’t reflexively pick more nines
🚨 A common mistake: aiming for 99.99% by default. Each nine costs roughly 10× more
(the nines), and past a point users can’t even tell
the difference.
Set the SLO from what users actually need:
- If users are on mobile networks with 99% reliability themselves, your 99.999% backend is invisible
to them — their connection is the bottleneck.
- An internal tool doesn’t need four nines; a payment system might.
- 🚨 The right SLO is “the point where making it better stops mattering to users.” More reliable
than that is wasted money that could fund features.
🎙️ “I wouldn’t reflexively target four nines — each nine is roughly 10× the cost, and if our users
are on mobile connections that are themselves 99% reliable, extra backend nines are invisible to them.
I’d set the SLO where reliability stops mattering to users and spend the difference on features.”
This “don’t over-target reliability” point is a strong, counter-intuitive interview signal.
Error budgets: the reframe
🚨 The most important idea here, and the thing that resolves the velocity-vs-stability fight.
If your SLO is 99.9%, you’re allowed to be unavailable 0.1% of the time — about 43 minutes a
month. That 0.1% isn’t failure; it’s a budget.
SLO: 99.9% → Error budget: 0.1% → ~43 minutes/month of allowed unavailability
Why this changes everything:
- It reframes reliability from “never fail” to “fail within budget.” “Never go down” is impossible
and leads to never shipping (every change is a risk). “Stay within 43 minutes a month” is a concrete
resource you spend.
- 🚨 It makes the velocity-vs-stability decision data-driven, not political:
- Budget remaining? Ship faster, take risks, deploy on Friday — you have room.
- Budget exhausted? Freeze features, focus on reliability, until it recovers.
- It aligns product and engineering on one number instead of arguing. The budget, not opinions,
decides whether to prioritize the next feature or reliability work.
🎙️ “Error budgets are what make this useful. 99.9% means we’re allowed 43 minutes of downtime a
month — that’s not failure, it’s budget. If we have budget left, we ship aggressively; if we’ve blown
it, we freeze features and fix reliability. It turns a political fight into a data-driven decision.”
This is Google SRE’s central operational innovation, and articulating it well is a genuine senior
signal.
Error budgets and alerting
The two connect directly: you alert on error-budget burn rate, not static thresholds.
- Fast burn (consuming the month’s budget in an hour) → page now, it’s a real incident.
- Slow burn (steady consumption over days) → ticket, a real but non-urgent problem.
This ties your alerting to the SLO, so alerts fire in proportion to actual user impact.
→ Monitoring & Alerting
Practical pitfalls
🚨 The “100% SLO” trap. Never target 100% — it’s impossible (dependencies fail, deploys happen),
infinitely expensive to approach, and leaves zero error budget, meaning you can never take any risk,
ship anything, or do maintenance. A 100% SLO is a sign someone doesn’t understand the framework. The
gap between 100% and your SLO is the room you have to operate.
Measure over a meaningful window — usually 28–30 days (a rolling month). Too short and single blips
dominate; too long and you can’t react.
Multiple SLOs for one service — availability and latency, since a service can be “up” but too
slow to be usable.
Dependencies constrain your SLO. 🚨 You can’t offer 99.99% if a critical dependency offers 99.9% —
your SLO is bounded by your dependencies (availability multiplies).
Know your dependency SLOs before promising yours.
Not everything needs an SLO. Focus on the critical user journeys (checkout, login, core reads),
not every endpoint. An SLO on an admin endpoint nobody depends on is noise.
⚖️ Trade-offs
| Choice |
Gain |
Cost |
| Higher SLO (more nines) |
More reliable |
~10× cost per nine; diminishing user benefit |
| SLA looser than SLO |
Buffer before penalties |
“We could promise more” pressure |
| Error budgets |
Data-driven velocity/stability decisions |
Requires org buy-in and discipline to enforce |
| Symptom-based SLIs |
Reflect real user experience |
Must measure at the right point |
| Fewer, focused SLOs |
Meaningful, actionable |
Some services uncovered |
In the real world
- Google SRE invented and popularized this framework, and the error-budget concept is its most
influential contribution — the free SRE book’s chapters on SLOs and error budgets are the definitive
reference and the source of everything here.
- The error budget resolving product-vs-ops tension is a real, repeatedly-reported organizational
win: instead of ops saying “no more deploys, it’s too risky” and product saying “we need to ship,”
both look at the budget. Budget left → ship. Budget gone → the deploy freeze is automatic and
non-negotiable, agreed in advance.
- The “we set our SLA equal to our SLO” mistake is common and painful — teams promise customers
exactly what they target internally, so every internal blip is a contract breach with refunds owed,
leaving no margin. Keeping the SLA well below the SLO is the standard fix.
🚨 Interview traps
- Confusing SLI/SLO/SLA. Measurement / target / contract. Get them straight.
- Setting the SLA equal to the SLO — no buffer, every miss is a penalty.
- Reflexively targeting more nines without justifying the cost or user need.
- Targeting 100% — impossible, and leaves no error budget.
- Not knowing error budgets — the central operational idea.
- Internal/cause-based SLIs (CPU) instead of user-facing ones.
- Ignoring that dependencies bound your SLO.
🎙️ Soundbites
- “SLI is what we measure, SLO is what we target, SLA is what we promise customers — and the SLA is
looser than the SLO, so an internal miss isn’t automatically a refund. The SLO is what drives
engineering.”
- “The error budget is the useful part: 99.9% means 43 minutes a month we’re *allowed to be down.
Budget left, we ship aggressively; budget gone, we freeze features. It turns velocity-vs-stability
from a political fight into a data-driven decision.”*
- “I wouldn’t reflexively target four nines — each nine is 10× the cost, and if our users are on 99%-
reliable mobile connections, extra backend nines are invisible. I’d set the SLO where reliability
stops mattering to users.”
- “Never target 100% — it leaves zero error budget, so you can never take a risk or do maintenance.
The gap between 100% and the SLO is the room to operate.”
- “SLIs should be user-facing symptoms — success rate and latency at the load balancer — not internal
metrics like CPU, and measured where the user actually experiences the system.”
🛠️ Try it
1. Define SLIs, SLOs, and an SLA for a service. Pick a real service. Write: two SLIs (availability
and latency, symptom-based), an SLO for each, and an SLA looser than the SLOs. Getting the three
levels distinct and correctly ordered is the exercise — most people conflate them on the first try.
2. Compute an error budget and spend it. For a 99.9% SLO, calculate the monthly error budget (~43
min). Then simulate: a bad deploy burns 20 minutes; a dependency outage burns 30. You’ve now blown the
budget — what does that mean for the next deploy? Feel the framework drive the decision.
3. Implement burn-rate calculation. From your error rate, compute how fast you’re consuming the
error budget. Distinguish a fast burn (page) from a slow burn (ticket). This connects SLOs to
alerting.
4. Justify an SLO to a skeptic. Argue why you’d target 99.9% not 99.99% for a given service.
Compute the cost difference and the user-visible difference. If the users are on flaky mobile, the
argument writes itself — and that’s the counter-intuitive insight worth internalizing.
Check yourself
1. What's the difference between an SLI, an SLO, and an SLA?
An **SLI** (Service Level Indicator) is the *measurement* — the actual observed value of a reliability
metric, like "99.95% of requests returned successfully in under 300ms last month." An **SLO** (Service
Level Objective) is your *internal target* for that indicator — "99.9% of requests under 300ms" — the
number you engineer toward and alert on. An **SLA** (Service Level Agreement) is a *contractual
promise* to customers, with financial or legal penalties for breach — "99.5% uptime or you get a
refund." The chain: you measure the SLI, compare it against your SLO, and the SLA (deliberately looser
than the SLO) is what you guarantee externally. The SLA should always be looser than the SLO so that
missing your internal target still leaves margin before you breach a contract.
2. Why should the SLA be looser than the SLO?
To create a buffer between "we missed our internal target" and "we breached a contract and owe
penalties." If your SLA promises customers 99.5% but you target 99.9% internally, then a bad month
that drops you to 99.7% misses your SLO (triggering internal reliability focus) but is still well above
the 99.5% you promised — no refunds, no contract breach. If instead the SLA equals the SLO (both
99.9%), then *every* internal miss is simultaneously a financial and legal event, leaving no room to
have an off month, do risky maintenance, or absorb a dependency's failure. The gap between the SLA and
the SLO is your margin of safety — it lets you manage reliability internally without every fluctuation
becoming a customer-facing penalty.
3. What is an error budget and how does it change decision-making?
An error budget is the amount of unreliability you're *allowed* by your SLO: a 99.9% SLO permits 0.1%
failure, about 43 minutes of downtime per month. Reframing that 0.1% as a budget rather than a failure
transforms the velocity-vs-stability argument from opinion into arithmetic. "Never go down" is
impossible and leads to never shipping (every change is a risk); "stay within 43 minutes a month" is a
concrete resource you spend deliberately. The decision rule becomes data-driven: if budget remains,
you can ship aggressively, take risks, and deploy freely; if the budget is exhausted, you freeze
features and focus on reliability until it recovers. This aligns product and engineering on a shared
number instead of a political fight — the budget, not who argues hardest, decides whether the next
priority is a feature or reliability work.
4. Why is targeting a 100% SLO a mistake?
Several reasons. It's impossible — dependencies fail, networks partition, deploys occasionally break
things, and physical infrastructure has non-zero failure rates, so no real system achieves 100% over
any meaningful period. It's infinitely expensive to even approach — each additional nine costs roughly
10× more, and 100% is the asymptote you can never reach. And critically, it leaves *zero error budget*:
with a 100% target, any downtime at all is a violation, which means you can never take a risk, ship a
change, or perform maintenance without "failing" your SLO — paralyzing the team. The whole error-budget
framework depends on the gap between 100% and your SLO being the room you have to operate. A 100% SLO
signals that someone doesn't understand the framework; the right target is the point where more
reliability stops mattering to users.
5. Why shouldn't you reflexively target more nines, and how do you choose the right SLO?
Because reliability past a certain point is invisible to users while remaining extremely expensive —
each nine costs roughly an order of magnitude more, and users literally cannot perceive the difference
above their own experience threshold. If your users access the service over mobile connections that
are themselves only ~99% reliable, then a 99.99% or 99.999% backend is entirely hidden by their own
connection's failures — you'd be spending 10-100× more for zero user-perceptible benefit, money that
could fund features. You choose the SLO by asking where reliability stops mattering to *users*: an
internal admin tool might be fine at 99%, a core purchase flow might justify 99.95%, and the deciding
factor is the actual cost of unavailability to users and the business, not a reflexive desire for more
nines. The right SLO is the point where making it better stops improving the user experience.
Further reading