These three acronyms get thrown around interchangeably in incident reviews and vendor contracts, and mixing them up leads to real mistakes: teams that alert on the wrong signal, promise customers more than they can measure, or treat a legal contract as if it were an engineering dashboard.
They aren't synonyms. A service level agreement (SLA), a service level objective (SLO), and a service level indicator (SLI) sit at three different layers of the same reliability system. The SLI is what you measure, the SLO is the target you hold that measurement to, and the SLA is the promise you make to a customer with money attached to it. Get the layering right and the rest of your reliability practice falls into place. This article explains each one mechanically, shows how they connect with real numbers, and covers the pitfalls that quietly break SLO programs.
The one-line version
Before the detail, here's the mnemonic that actually holds up:
- SLI is the measurement. "99.93% of requests over the last 28 days returned a non-error response."
- SLO is the target for that measurement. "99.9% of requests should succeed."
- SLA is the contract. "If availability drops below 99.5% in a billing month, the customer gets a 10% credit."
The SLI is a number your telemetry produces. The SLO is a line you draw on that number. The SLA is a business document that references a (usually looser) version of that line and specifies what happens when you cross it.
SLI: the measurement
A service level indicator is a quantitative measure of how your service is behaving, framed from the user's point of view. The form that works best, and the one the Google SRE workbook recommends, is a ratio of good events to valid events:
1SLI = good events / valid events × 100%
This scale is the reason the ratio form is worth the effort: 0% means everything is broken, 100% means nothing is. An availability SLI counts requests that returned a non-error status against all valid requests. A latency SLI counts requests served faster than some threshold against all valid requests.
Say you want to measure availability of a checkout API. The "valid events" are all the HTTP requests that hit it, excluding things that don't reflect service health (health checks, load-test traffic). The "good events" are the ones that returned a 2xx or 3xx. If 999,300 out of 1,000,000 requests succeeded over your window, your SLI is 99.93%.
Latency works the same way, except "good" is defined by a duration rather than a status code. If you decide a request is "good" when it completes in under 200 ms, your latency SLI is the fraction of requests that beat that bar. Note what this does not do: it does not average the latency. That distinction matters more than almost anything else in this article, and we'll come back to it in the pitfalls.
SLO: the target
A service level objective is the target value you set for an SLI over a defined compliance window. "99.9% of requests succeed, measured over 28 days" is an SLO. It has three parts: the indicator (success ratio), the target (99.9%), and the window (28 days).
The window is not a detail you can skip. "99.9% availability" with no window is meaningless, because 99.9% over an hour and 99.9% over a quarter allow wildly different amounts of downtime. Rolling windows (the trailing 28 days) are usually better than calendar windows (this month) because they don't reset your budget to full at midnight on the first, which is exactly when a bad deploy tends to land.
The Google SRE book offers a clean test for whether you're looking at an SLO or an SLA: ask what happens if you miss it. If the answer is "we investigate and prioritize reliability work," it's an SLO. If the answer is "we owe the customer money," it's an SLA.
Error budgets: the useful part of an SLO
An SLO implies an error budget, which is simply the failure you're allowed:
1error budget = 100% - SLO
A 99.9% SLO gives you a 0.1% error budget. Concretely, if your service handles 1,000,000 requests over the window, you're allowed 1,000 failures before you've breached. That is the entire point of setting an SLO below 100%: you're explicitly buying yourself room to ship features, run risky migrations, and absorb the occasional bad deploy without treating every failed request as a fire.
Converted to downtime, the budget shrinks fast with every extra nine. Over a 30-day month:
| SLO | Error budget | Allowed downtime per month |
|---|---|---|
| 99% | 1% | ~7.2 hours |
| 99.9% | 0.1% | ~43 minutes |
| 99.95% | 0.05% | ~22 minutes |
| 99.99% | 0.01% | ~4.3 minutes |
| 99.999% | 0.001% | ~26 seconds |
The jump from 99.9% to 99.99% looks small on paper and costs an enormous amount in engineering effort. Each nine typically requires more redundancy, more automation, and more on-call pain, while delivering diminishing returns to users who can't perceive the difference. Chasing 100% is almost always the wrong call.
Burn rate is the companion concept: how fast you're spending the budget relative to the window. A burn rate of 1 means you'll exhaust the budget exactly at the end of the window. A burn rate of 14 means you'll be out in a fraction of it, which is what you want to page a human about. Alerting on burn rate instead of on individual failed requests is what separates a mature SLO from a noisy threshold alert.
SLA: the promise
A service level agreement is a formal, customer-facing contract that guarantees a level of service and specifies consequences when you fall short, usually service credits or penalties. Legal and business teams own it, not engineering, and it's deliberately built on simple, unambiguous metrics like monthly availability. There's no room for nuance in "the service will be available 99.5% of the time"; it either was or it wasn't.
Not every service has an SLA. Google Search has no public SLA, and that's intentional: Google never signed a contract with the entire internet. Plenty of internal services have SLOs and no SLA at all. The SLA exists specifically when there's an external party with leverage and money on the line.
How the three fit together
Here's the relationship in one scenario. You promise customers 99.9% availability in your SLA, with credits if you breach. Internally, your team sets a stricter 99.95% SLO as a safety buffer. Your telemetry reports a measured SLI of 99.93% over the last 28 days.
In that month you met the SLA (99.93% > 99.9%, no credits owed) but missed your internal SLO (99.93% < 99.95%). That gap is the whole design working as intended: the SLO tripped before the SLA did, giving your team an early warning to invest in reliability before a customer-facing breach and a check to the customer. Your SLA should always be looser than your SLO, and your SLO is only as trustworthy as the SLI feeding it.
Common pitfalls
Averaging latency instead of counting it. A p50 or mean latency of 180 ms can hide the fact that 5% of your users are waiting three seconds. Averages smear tail latency into invisibility. Define your latency SLI as the fraction of requests under a threshold, and track the actual percentiles (p95, p99) separately so you can see the tail.
Measuring at the load balancer, not the user. An availability SLI computed from your load balancer's success rate will look great while users stare at spinners, because the load balancer returned a 200 with a broken payload, or the failure happened in a downstream call it never saw. Measure as close to the user's actual experience as you can, and count the things that make a response genuinely useful, not just present.
Setting the SLO equal to the SLA. If your internal target is the same number you promised customers, you have no buffer. The moment your SLI dips, you're already breaching the contract. The SLO is supposed to trip first and give you runway.
Tracking too many SLIs. Teams rarely suffer from too few SLIs. The usual problem is the opposite: dozens of them, none of which anyone actually watches. Pick the two or three that reflect user happiness for a given service (typically availability and latency, sometimes correctness) and ignore the rest.
Aiming for 100%. A 100% SLO leaves zero error budget, which means every deploy is a potential breach and your team optimizes for never shipping. It also causes literal division-by-zero problems in some SLO tooling. Pick a target that reflects what users actually need, then spend the budget deliberately.
Final thoughts
SLA, SLO, and SLI describe three layers of the same idea: the promise, the target, and the measurement. The SLI is where it all grounds out, because an SLO built on a misleading indicator (a latency average, a load-balancer success rate) will pass right up until your users revolt. Get the measurement close to the user, set the target below 100% so you have an error budget to spend, and keep the SLA looser than the SLO so your internal alarms fire first.
Doing this well means treating reliability as part of your broader observability practice: computing SLIs from real telemetry and watching error-budget burn rate over a rolling window instead of eyeballing dashboards. Dash0's Service Level Objectives track an error budget over a time window and alert on burn rate rather than on every individual violation, with error-budget burndown and burn-rate views that show you exactly how fast you're spending. Because it's OpenTelemetry-native and 100% PromQL-compatible, you define SLIs directly against your metrics, logs, and traces in one place, measured where your users actually are.
Start a free trial to explore your telemetry and define the SLIs your reliability depends on. Error-budget and burn-rate tracking through SLOs is currently in private beta, enabled per account by the Dash0 team. No credit card required.