SLOs and error budgets

How to pick SLIs, set an SLO, alert on burn rate and use the error budget to decide between shipping features and fixing reliability.

Updated 2026-11-11Raw markdown

Strategy sections
On this page

Use this page when a service has no reliability target, when alerts are noisy and you want to page on user impact instead, or when someone asks "is this reliable enough?".

Start with what the user feels

An SLI is a ratio of good events to valid events. Pick one or two per user journey.

Journey SLI Good event
API request Availability Response is not a 5xx
API request Latency Response under 300 ms
Payment or checkout Success Transaction completes without a system error
Batch or file transfer Freshness Job finished before its deadline
Queue consumer Lag Message processed within 60 s
  • Measure at the edge closest to the user (load balancer, API gateway), not on the host.
  • Exclude events that are not your fault on purpose (client 4xx), and write down why.

Set the target from data, then round down

  1. Pull 28 to 90 days of the SLI.
  2. See what you actually achieved. If you hit 99.95 percent, start at 99.9 percent.
  3. Agree the target with the service owner and the product owner.
SLO Error budget per 30 days
99% 7 h 12 min
99.5% 3 h 36 min
99.9% 43 min
99.95% 22 min
99.99% 4.3 min

$$\text{error budget} = (1 - \mathrm{SLO}) \times \text{window}$$

Worked example
43.2minutes of budget

At 99.9% over 30 days: \(0.001 \times 43{,}200 = 43.2\) minutes.

Alert on burn rate, not on single spikes

Burn rate is how fast you are spending the budget. A burn rate of 1 spends exactly the budget over the window.

$$\text{burn rate} = \frac{\text{observed error rate}}{1 - \mathrm{SLO}}$$

Worked example
14.4×burn rate
50 hbudget gone

At a 99.9% SLO, a 1.44% error rate is a burn rate of \(0.0144 / 0.001 = 14.4\). Held for one hour, that spends 2% of the 30-day budget, and the whole budget in 50 hours.

Error budget remaining, 99.9% SLO over 30 daysAt 14.4× burn the budget is gone in 50 hours. At 1× it lasts the month.
Error budget remaining over 30 days at 1x and 14.4x burnTwo falling lines for a 99.9 percent SLO. At a burn rate of 1 the budget falls steadily and reaches zero at day 30. At a burn rate of 14.4 it falls 14.4 times faster and reaches zero after 50 hours, a little over 2 days.0255075100051015202530Days into the 30-day windowError budget remaining (%)Gone at 50 h14.4× burn1× burngone at day 30
Alert Long window Short window Burn rate Action
Fast burn 1 h 5 min 14.4 Page
Slow burn 6 h 30 min 6 Page
Very slow burn 3 d 6 h 1 Ticket

Both windows must exceed the rate before the alert fires. For the fast-burn row at 99.9%, that means an error rate above 1.44% in both the last hour and the last 5 minutes. That keeps alerts fast and stops them flapping.

# Generic shape, adapt to your monitoring tool
slo:
  service: <service>
  sli: availability
  good: sum(requests{service="<service>",code!~"5.."})
  valid: sum(requests{service="<service>"})
  target: 0.999
  window: 30d
alerts:
  - name: <service>-slo-fast-burn
    burn_rate: 14.4
    windows: [1h, 5m]
    notify: "@<team-oncall-handle>"

Use the budget to make decisions

  • Budget healthy: ship features, run experiments, do risky migrations.
  • Budget below 25 percent: slow risky changes, prioritise reliability work.
  • Budget spent: freeze non-urgent changes to the service until it recovers, except reliability fixes.
  • Write this policy down and get the product owner to sign it before you need it.

Roll out SLOs in small steps

  • Pick the two or three services that matter most to revenue or customers.
  • One availability and one latency SLO each.
  • Dashboards first, alerts second, policy third.
  • Review monthly: was the SLO right, did alerts fire when users were hurt?

Dependencies cap your SLO

Services in series multiply their availability. Redundant copies combine the other way.

$$A_{\text{series}} = \prod_i A_i \qquad A_{\text{parallel}} = 1 - \prod_i (1 - A_i)$$

Worked example
99.7%in series
99.99%in parallel

Three 99.9% services in series give \(0.999^3 \approx 99.7\%\). Two 99% replicas in parallel give \(1 - 0.01^2 = 99.99\%\), assuming they fail independently.

Pitfalls

  • Starting with 99.99 percent because it sounds good. You will burn it on dependencies you do not control.
  • SLIs from CPU or host health. Users do not feel CPU.
  • Too many SLOs. Nobody reads twenty.
  • An SLO with no policy. Then it is just a graph.