SLA, SLO and SLI: the contractual layer
"What's the difference between an SLA, an SLO and an SLI, and why does it matter?"
What they are
Three layers, and the relationship between them is the point rather than the definitions.
SLI Service Level INDICATOR
A measurement. "The proportion of HTTP requests that
return a non-5xx status within 300 ms."
A number, with a precise definition of what counts.
SLO Service Level OBJECTIVE
A target for an SLI, over a window.
"99.9% of requests, measured over 28 rolling days."
An INTERNAL commitment. Its purpose is to drive
engineering decisions.
SLA Service Level AGREEMENT
A contract with a customer, containing an SLO and a
CONSEQUENCE for missing it.
"99.5% monthly, or a 10% service credit."
An EXTERNAL, legal commitment.
The relationship that matters: the SLA target should be looser than the SLO target, and the gap is deliberate.
SLI measured availability, currently 99.94%
SLO 99.9% internal. Breaching triggers engineering action.
SLA 99.5% external. Breaching triggers a refund.
The gap between 99.9% and 99.5% is your margin: you find out
you have a problem, and act, before a customer is owed money.
Commonly confused in a specific way: teams write an SLA and call it an SLO, so the first signal of trouble is a customer credit rather than an internal alert. Setting them equal removes the entire warning margin.
Also commonly confused: an SLO is not a target for how good the service should be. It is a target for how bad it is allowed to get, and that inversion is what makes the error budget work.
The problem it solves
Without this structure, reliability arguments have no arithmetic:
"The service should be more reliable." -> how much more?
"Reliability is important." -> more than what?
"We need to reduce incidents." -> to what number?
"Can we ship faster?" -> at what cost?
The SLO converts all of those into one number that both engineering and product can reason about, and the error budget is what makes it a decision tool rather than a report.
SLO 99.9% over 28 days
-> allowed downtime: 0.1% x 28 x 24 x 60 = 40.3 minutes
-> that 40.3 minutes is the ERROR BUDGET
Spent 8 minutes this month? 80% remaining. Ship features.
Spent 39 minutes? 3% remaining. Freeze risky changes.
The reframe worth stating: an unspent error budget is waste. A service running at 99.999 percent against a 99.9 percent SLO is over-invested in reliability, and that investment came out of feature work. 100 percent is the wrong target for everything except the few things where it genuinely is right.
Mechanics
Defining an SLI precisely
Most SLO work fails here, not at the target. A vague SLI produces a number nobody trusts.
BAD: "availability"
Measured how? Where? Which requests? What is a failure?
GOOD: "The proportion of HTTP requests to /api/v1/* received
at the load balancer, excluding requests with a 4xx
status other than 429, that return a non-5xx status
within 300 ms, measured in 1-minute buckets."
Every clause in that is doing work:
"received at the load balancer" WHERE it is measured. Server-side
misses the failures that never
arrived; client-side includes the
user's bad wifi.
"excluding 4xx other than 429" A client sending malformed input
is not your outage. 429 IS
yours, because you rejected it.
"non-5xx within 300 ms" Slow is a failure. A request
that succeeds after 30 seconds
has failed from the user's view.
"1-minute buckets" The aggregation granularity,
which changes the number.
The three SLI shapes, and which to use:
REQUEST-BASED good_requests / total_requests
The default. Simple, and it under-weights
outages during low traffic: a total outage
at 3am costs almost no budget.
WINDOWS-BASED good_minutes / total_minutes
A minute is "good" if it met a threshold.
Weights every minute equally, so a 3am
outage costs the same as a midday one.
Closer to how customers experience it.
USER-BASED users_with_good_experience / total_users
The most honest and the hardest. One user
hitting a broken shard is 100% broken for
them, and invisible in a request-based SLI.
Request-based is the default and windows-based is often more honest, and the choice should be deliberate rather than inherited from whatever the monitoring tool computes.
Choosing the target
Not by aspiration. By three inputs:
1. WHAT DO USERS ACTUALLY NOTICE?
If the client retries transparently and the mobile network
already drops 0.5% of requests, the difference between
99.9% and 99.99% is invisible to a user.
2. WHAT IS THE CURRENT PERFORMANCE?
Measure for a month before setting a target. An SLO set
above current performance is a project; an SLO set far
below it is meaningless. Set it near current performance
and tighten deliberately.
3. WHAT DOES EACH NINE COST?
Each nine is roughly 10x the engineering effort of the one
before, and the cost is not linear in value.
SLO Downtime per 30 days Typical requirement
99% 7h 12m one machine, best effort
99.9% 43m redundancy, monitoring, on-call
99.95% 21m multi-AZ, automated failover
99.99% 4m 19s multi-region, no manual steps
in the recovery path
99.999% 26s nothing human in the loop;
a deploy is a bigger risk than
a failure
The observation to make: at 99.99 percent, 4 minutes and 19 seconds per month means a human cannot be involved in recovery, because a page, a wake-up and a login exceeds the entire budget. That single fact tells you what the SLO implies architecturally, and it is a better way to explain the cost of a nine than any percentage.
The dependency constraint
You cannot promise more availability than your dependencies provide.
Your service depends on:
auth service 99.95%
database 99.99%
payments API 99.9%
If ALL are required (serial dependency):
0.9995 x 0.9999 x 0.999 = 0.99840
-> 99.84% is your CEILING. An SLO of 99.9% is not
achievable without changing the architecture.
The options, and this is the design conversation the arithmetic produces:
DEGRADE GRACEFULLY Make the payments API optional for the
request path, so its 99.9% no longer
multiplies in. This is usually the answer.
CACHE Serve from cache when auth is down, with a
bounded staleness. Removes it from the
critical path most of the time.
REDUNDANCY Two providers for the same capability, so
the combined availability is 1 - (1-a)^2.
SET A LOWER SLO Honest, and sometimes correct.
See composite SLOs for the full arithmetic.
The SLA, and why it is a different document
An SLA needs things an SLO does not:
A MEASUREMENT METHOD both parties accept.
Whose numbers? Yours, theirs, or a third party's? This is
negotiated and it matters: your load balancer's view and
the customer's synthetic monitor will disagree.
EXCLUSIONS.
Scheduled maintenance windows, force majeure, the
customer's own misconfiguration, and failures of things
outside your control.
A CLAIM PROCESS.
Who reports a breach, within what window, with what
evidence.
A CONSEQUENCE.
Service credits, typically tiered: 10% credit below
99.5%, 25% below 99%, 100% below 95%.
Note that credits are usually capped at the monthly fee,
which means the SLA's financial exposure is bounded and
much smaller than the customer's actual loss.
The asymmetry worth naming: an SLA credit almost never compensates the customer's real cost. A customer whose business stopped for four hours gets a percentage of one month's fee. So an SLA is a signal of confidence and a bounded liability, not insurance, and customers who need real protection negotiate something else.
A worked example: setting the first SLO
Service: the product API. No SLO today. Product asks for
"four nines".
STEP 1: measure for four weeks before committing to anything.
Measured availability (non-5xx within 300 ms at the LB):
week 1 99.94%
week 2 99.89% (one 12-minute incident)
week 3 99.97%
week 4 99.91%
Four-week aggregate: 99.93%
STEP 2: price the ask.
99.99% = 4m 19s per 30 days. Our single incident last month
was 12 minutes, so ONE incident of that size blows nearly
three months of budget.
Reaching it requires: multi-region active-active, automated
failover with no human step, and a deploy process that
cannot cause a 4-minute outage.
Estimate: two quarters of platform work, plus roughly a 60%
increase in infrastructure cost for the second region.
STEP 3: check the dependency ceiling.
auth 99.95% x database 99.99% x search 99.9% = 99.84%.
*** 99.99% is not achievable at all without removing search
from the critical path. *** This ends the conversation
about four nines, on arithmetic rather than opinion.
STEP 4: propose what is real.
SLO: 99.9% (43 minutes per 30 days), which is above current
performance but reachable, and just inside the dependency
ceiling.
SLA: 99.5% (3h 39m), giving a large margin between the
internal alarm and the customer credit.
STEP 5: make search optional, which raises the ceiling.
Degrade to a cached popular-items list when search is down.
New ceiling: 0.9995 x 0.9999 = 99.94%.
This one change buys more headroom than a quarter of
reliability work, and it is a week.
STEP 6: agree the error budget policy BEFORE spending it.
What happens at 0% remaining, agreed and signed while
nobody is in an incident.
Step 3 is where the arithmetic changes the conversation, and step 5 is the finding that matters: making one dependency optional bought more availability than a quarter of reliability engineering would have. That is the pattern, and it is why the dependency ceiling calculation comes early.
Production evidence
Google's Site Reliability Engineering book, chapters 3 and 4, defines the SLI/SLO/SLA distinction and the error budget, and is explicit that 100 percent is the wrong target and that an unspent budget represents over-investment.
The SRE Workbook, chapter 2, gives the practical SLI menu (request-based, windows-based, user-based) and the argument that SLI specification is where most of the difficulty lives.
AWS's published SLAs are a useful reference for the structure: a tiered credit schedule, explicit exclusions, a claim window, and credits capped at the monthly charge for the affected service, which is the bounded-liability shape described above.
Google Cloud's and Azure's composite SLA documentation both state explicitly that the combined SLA of dependent services is the product of the individual SLAs, which is the dependency ceiling arithmetic as vendor guidance.
Nobl9's and Datadog's SLO tooling implement rolling windows, burn-rate alerting and multi-window multi-burn-rate alerts, which is direct evidence that the calendar-month window was found inadequate in practice.
The debate
The case for formal SLOs: they convert reliability from an argument into arithmetic. The error budget makes "can we ship faster" answerable, and it gives engineering a defensible way to say no that product can verify.
The case against: SLOs become theatre. A team sets 99.9 percent, never measures it carefully, never enforces the policy, and the number is quoted in slides while nothing about engineering behaviour changes. An SLO with no enforced consequence is a decoration, and most SLOs in practice are decorations.
The case for user-based SLIs over request-based: request-based hides the failure that matters most, which is one user experiencing 100 percent failure while the aggregate looks fine.
My position: measure before you target, set the SLO near current performance, keep the SLA well below it, and do not create an SLO without a signed error budget policy.
The sequence matters. Measuring for a month before committing is the step teams skip, and skipping it produces either a target you are already missing (which is a project disguised as an SLO) or one so loose it never triggers anything. Set it near current performance and tighten deliberately once the policy is working.
The gap between SLO and SLA is the one I would not compromise on. If they are equal, the first signal of a problem is a customer credit, and you have given up the entire warning margin. 99.9 internal against 99.5 external gives you a real window to act in.
The calculation I would do first, before any target discussion, is the dependency ceiling. In the worked example it ended the four-nines conversation on arithmetic rather than opinion, and it surfaced that making search optional bought more availability in a week than a quarter of reliability work would. That is the pattern: the highest-value availability work is usually removing something from the critical path, not making it more reliable.
And the thing that determines whether any of this is real: the error budget policy has to be signed before the budget is spent. A policy agreed during an incident is not a policy, it is a negotiation you will lose. See the error budget policy.
Where I would push back on a request for more nines: ask what users actually notice. If the mobile client retries transparently and the network already drops half a percent of requests, the difference between 99.9 and 99.99 is invisible to every user and costs two quarters of platform work.
Follow-up Q&A
"What's the difference between the three?" An SLI is a measurement, an SLO is an internal target for that measurement, and an SLA is a contract with a customer containing a target and a consequence. The relationship is what matters: the SLA target should be looser than the SLO target, so you find out you have a problem and act before a customer is owed money. Teams that set them equal have given up their entire warning margin, and the first signal of trouble becomes a credit request.
"How do you define an SLI?" Precisely enough that two people compute the same number.
Where it is measured, which requests count, what counts as a failure, and at what granularity.
"The proportion of requests to /api/v1/* at the load balancer, excluding 4xx other than 429,
that return non-5xx within 300 milliseconds, in one-minute buckets." Every clause does work:
server-side measurement misses requests that never arrived, a client's malformed input is not
your outage but a 429 is, and slow is a failure because a request succeeding after thirty
seconds has failed from the user's view.
"How do you choose the target?" Three inputs, and aspiration is not one. What users actually notice, because if the client retries transparently the difference between three and four nines is invisible. Current measured performance, which means measuring for a month before committing, because a target above current performance is a project disguised as an SLO. And what each nine costs, which is roughly ten times the previous one.
"How do you explain what a nine costs?" In minutes rather than percentages. 99.99 percent is four minutes nineteen seconds per thirty days, which means a human cannot be in the recovery path at all: a page, a wake-up and a login exceeds the entire monthly budget. That one fact tells you the architecture the SLO implies, and it lands better than any argument about diminishing returns.
"Can you promise 99.99 if your dependencies are 99.95, 99.99 and 99.9?" No, and the arithmetic ends the conversation. If all three are required, the ceiling is their product, 99.84 percent, so even 99.9 is not achievable. The useful next move is not more reliability work, it is removing something from the critical path: making the 99.9 percent search dependency optional with a cached fallback took the ceiling to 99.94 in one week, which is more than a quarter of reliability engineering would have bought.
"Request-based or windows-based SLI?" Request-based is the default and windows-based is often more honest. Request-based under-weights outages during low traffic, so a total outage at 3am costs almost no error budget while being a real outage. Windows-based counts every minute equally. User-based is the most honest and hardest: one user hitting a broken shard experiences 100 percent failure and is invisible in a request-based aggregate.
"What's actually in an SLA that isn't in an SLO?" A measurement method both parties accept, which is negotiated and matters because your load balancer's view and the customer's synthetic monitor will disagree. Exclusions for maintenance windows and customer misconfiguration. A claim process with a reporting window. And a consequence, usually tiered service credits capped at the monthly fee. That cap is worth naming: a customer whose business stopped for four hours gets a percentage of one month's bill, so an SLA is a signal of confidence and a bounded liability rather than insurance.
"When is an SLO theatre?" When there is no enforced consequence. A team sets 99.9 percent, quotes it in slides, never carefully measures it and never changes behaviour when the budget is spent. Most SLOs in practice are like that. The thing that makes it real is an error budget policy agreed and signed before the budget is spent, because a policy negotiated during an incident is not a policy.
Common misconceptions
"The SLO and SLA should match." The gap between them is your warning margin. Equal targets mean the first signal is a customer credit.
"An SLO is a target for how good the service should be." It is a target for how bad it is allowed to get, which is the inversion that makes the error budget work.
"100 percent is the goal." An unspent error budget is over-investment paid for out of feature work. 100 percent is right for very few things.
"Availability is a well-defined term." It is whatever the SLI definition says. Where it is measured and what counts as a failure change the number substantially.
"An SLA protects the customer." Credits are typically capped at the monthly fee, which is far below the customer's real loss. It is a confidence signal and a bounded liability.
Interview delivery note
Give the three definitions quickly and spend the time on the relationship, because that is the part people get wrong: "An SLI is the measurement, an SLO is the internal target, an SLA is the customer contract with a consequence. What matters is that the SLA is looser than the SLO, so you find out and act before a customer is owed money. Teams that set them equal have given up the warning margin entirely."
Make the cost of a nine concrete: "99.99 percent is four minutes nineteen seconds a month, which means a human can't be in the recovery path at all: a page, a wake-up and a login blows the whole budget. That's a better way to explain what a nine costs than any argument about diminishing returns."
Do the dependency arithmetic unprompted, because it settles the question: "And before agreeing a target I'd compute the ceiling. Auth at 99.95, database at 99.99 and search at 99.9, all required, multiplies to 99.84, so 99.9 isn't achievable and 99.99 isn't close. That ends the conversation on arithmetic rather than opinion."
Then the move that follows from it, which is the staff-level insight: "and the fix isn't more reliability work on those dependencies. It's removing one from the critical path. Making search optional with a cached fallback took the ceiling to 99.94 in a week, which is more than a quarter of reliability engineering would have bought."
Close on what makes it real: "and I wouldn't create an SLO without a signed error budget policy, because an SLO with no enforced consequence is a decoration, and most SLOs in practice are decorations."
Further reading
- Beyer et al., Site Reliability Engineering, chapters 3 and 4.
- Beyer et al., The Site Reliability Workbook, chapter 2, for the SLI menu and worked examples.
- AWS and Google Cloud published SLAs, for the structure of exclusions, claim processes and credit tiers.
- Google Cloud's composite SLA documentation, for the dependency-multiplication arithmetic as vendor guidance.