---
title: SLOs and error budgets
slug: slos-and-error-budgets
summary: How to pick SLIs, set an SLO, alert on burn rate and use the error budget to decide between shipping features and fixing reliability.
order: 5
updated: 2026-11-11
status: ready
---

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}$$

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}}$$

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.

| 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.

```yaml
# 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)$$

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.
