Sign in
← Observability
11 min · medium · Lesson 6 of 6

SLI, SLO, and error budget

How to measure reliability in numbers: SLI as a quality metric, SLO as the target, and the error budget as your license to take risks.

Why this matters

You can't verify that "the service is working well." That's a feeling, not an engineering statement. To talk about reliability in concrete terms, you measure it, and there are three concepts for that: SLI, SLO, and error budget. They turn the vague word "reliable" into numbers you can base decisions on: ship a release today, or work on stability first.

This lesson wraps up the module. The Prometheus metrics, Grafana dashboards, and alerts from earlier lessons come together here into one system: the SLI is computed from metrics, drawn on a dashboard, and an alert fires on budget burn.

SLI: what we measure

SLI (Service Level Indicator) is a metric of service quality from the user's point of view. Not "CPU is at 60% load," but something the user actually feels:

It's convenient to write the SLI as the share of "good" events among all events. That way it always falls between 0 and 1, and it's easy to compare against a target.

SLI = good requests / all requests

What counts as a good request is decided in advance. A 5xx response means the service failed. That's a bad event. A 404 for an order that doesn't exist is the service responding correctly; the client made the mistake. That's why 4xx usually doesn't count as a failure. Put it in the "bad" bucket and the SLI will show an outage where there isn't one.

SLI in PromQL

The metrics from the Prometheus lesson already have everything you need. The http_requests_total counter with a status label gives you both the numerator and the denominator:

sum(rate(http_requests_total{job="api", status!~"5.."}[5m]))
/
sum(rate(http_requests_total{job="api"}[5m]))

There are three details here, and skipping any one of them breaks the SLI.

Expressions like this get long, and nobody rewrites them in every panel. They're saved as a recording rule: Prometheus evaluates the expression itself on every rule cycle and writes the result into a new series with a readable name. The documentation recommends names of the form level:metric:operations, for example sli:availability:ratio_rate5m.

groups:
  - name: api-slo
    rules:
      - record: sli:availability:ratio_rate5m
        expr: |
          sum(rate(http_requests_total{job="api", status!~"5.."}[5m]))
          /
          sum(rate(http_requests_total{job="api"}[5m]))

SLO: what target to set

SLO (Service Level Objective) is a target for the SLI: what value counts as good enough over a period. Not 100%, but a realistic bar.

SLI: share of successful requests
SLO: 99.9% successful requests over 30 days

99.9% sounds almost perfect, but over 30 days that's about 43 minutes during which requests can fail. SLO is set below 100% on purpose. Absolute reliability costs an infinite amount, and the user won't notice the difference between 99.9% and 100% anyway: their own Wi-Fi and mobile network already fail more often than that.

Don't confuse SLO with SLA. SLA (Service Level Agreement) is a contract with the client that spells out what happens on a breach: a penalty, a discount, a refund. SLO is an internal engineering target. It's usually set stricter than the SLA, so the team notices a problem before any payouts start.

Error budget: license to take risks

If the SLO is 99.9%, the remaining 0.1% is the allowed share of failures. It's called the error budget. It's a license to fail that you can spend.

error budget = 1 - SLO
SLO 99.9% → budget 0.1% → 30 days × 24 h × 60 min × 0.001 ≈ 43 minutes

The same calculation for other targets:

SLOBudget over 30 days
99%432 min (7.2 h)
99.9%43.2 min
99.99%4.32 min

Each extra nine shrinks the budget by a factor of 10. For a request-based SLI, "minutes" is a convenient fiction: the budget is really in requests. At 99.9%, out of every million requests, 1,000 are allowed to fail.

The budget turns reliability into a decision-making tool:

This settles the age-old argument where development wants to ship faster and operations wants stability. While there's budget, you ship. Once it's gone, you stabilize. The decision is made by the number. What exactly to do once the budget runs out, the team writes down in advance in an error budget policy.

Burn rate: how fast the budget is spent

Knowing how much budget is left isn't enough. You also need to know how fast it's draining. That speed is called burn rate:

burn rate = current error share / error share allowed by SLO

A burn rate of 1 means the service is spending its budget at exactly the rate that uses it all up by the end of the 30-day window. A burn rate of 5 means the whole month's budget will be gone in 6 days. Example: SLO 99.9% allows 0.1% errors, and the service is currently returning 0.5%. Burn rate = 0.5 / 0.1 = 5.

In PromQL, it's convenient to compute burn rate on top of the SLI recording rule:

(1 - sli:availability:ratio_rate5m) / (1 - 0.999)

Connecting to alerts

SLO tells you what to alert on. The alert from the previous lesson is most useful when it's tied to budget burn. "The budget is burning 14 times faster than normal" matters more than a raw threshold on a metric. That's an alert on the symptom the user feels, not on the cause.

- alert: ApiErrorBudgetBurn
  expr: (1 - sli:availability:ratio_rate1h) / (1 - 0.999) > 14.4
  for: 2m
  labels:
    severity: page

Where 14.4 comes from. The Google SRE Workbook suggests paging a human if 2% of the monthly budget burns in an hour. 2% of 30 days packed into 1 hour gives a burn rate of 0.02 × 720 / 1 = 14.4. Slow burn (10% of the budget over 3 days, burn rate 1) becomes a ticket, not a 2 a.m. phone call. In production, alerts like this are usually built on two windows at once, a long one and a short one. The long window confirms the budget really is being spent, and the short one lets the alert clear quickly once the fix lands.

In this lesson's labs the windows are shorter (1 minute instead of an hour, for in seconds), so you see the result right away. The formulas are the same.

Common mistakes

What you'll need for the tasks

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 3 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson observability-basics-06-slo-sli