- ds
- Operations
- SLO and error budget
SLO and error budget
Target, current level, budget left and burn rate.
checkout-api availability
99.9% of requests succeed · 21 Sep to 20 Oct · day 21 of 30
- Objective
- 99.90%
- Current
- 99.89%
- Budget left
- 12.1of 43.2 min
- Burn, 1h
- 0.8×
Show code
<section class="slo">
<header class="slo-head">
<div><h3>checkout-api availability</h3><p>99.9% of requests succeed · 21 Sep to 20 Oct · day 21 of 30</p></div>
<span class="badge warn">Budget 72% spent</span>
</header>
<dl class="slo-figs">
<div><dt>Objective</dt><dd>99.90%</dd></div>
<div><dt>Current</dt><dd class="warn">99.89%</dd></div>
<div><dt>Budget left</dt><dd class="warn">12.1<small>of 43.2 min</small></dd></div>
<div><dt>Burn, 1h</dt><dd>0.8×</dd></div>
</dl>
<div class="budget">
<div class="budget-row"><span>Error budget remaining</span><b>28%</b></div>
<div class="budget-bar warn" style="--v:0.280;--at:0.300"><i></i><b></b></div>
</div>
<div class="plot" style="--h:9rem" role="img" aria-label="Error budget remaining: 12.1 of 43.2 minutes after 21 days, 20 minutes of it spent in one incident on day 17">
<div class="ch-grid"><i style="--at:0" data-v="0m"></i><i style="--at:0.2" data-v="10m"></i><i style="--at:0.4" data-v="20m"></i><i style="--at:0.6" data-v="30m"></i><i style="--at:0.8" data-v="40m"></i><i style="--at:1" data-v="50m"></i></div>
<svg viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><path class="ch-line s6 dash" d="M0 13.6L4.76 16.48L9.52 19.36L14.29 22.24L19.05 25.12L23.81 28L28.57 30.88L33.33 33.76L38.1 36.64L42.86 39.52L47.62 42.4L52.38 45.28L57.14 48.16L61.9 51.04L66.67 53.92L71.43 56.8L76.19 59.68L80.95 62.56L85.71 65.44L90.48 68.32L95.24 71.2L100 74.08"/><path class="ch-fill c-warn" d="M0 13.6L4.76 14.4L9.52 15.6L14.29 16.2L19.05 17.2L23.81 17.6L28.57 19.2L33.33 20L38.1 20.6L42.86 22.8L47.62 23.8L52.38 24.6L57.14 25.8L61.9 26.4L66.67 27.4L71.43 28.8L76.19 29.6L80.95 70L85.71 72.8L90.48 74L95.24 75L100 75.8L100 100L0 100Z"/><path class="ch-line c-warn" d="M0 13.6L4.76 14.4L9.52 15.6L14.29 16.2L19.05 17.2L23.81 17.6L28.57 19.2L33.33 20L38.1 20.6L42.86 22.8L47.62 23.8L52.38 24.6L57.14 25.8L61.9 26.4L66.67 27.4L71.43 28.8L76.19 29.6L80.95 70L85.71 72.8L90.48 74L95.24 75L100 75.8"/></svg>
<i class="ch-mark down" style="--x:0.7619" data-v="INC-226"></i>
<div class="ch-x"><span style="--at:0">21 Sep</span><span style="--at:1">Today</span></div>
</div>
</section>One objective, everything needed to judge it. The figures say where you stand, the bar says how much room is left, and the burn-down shows when it went. The tick on the bar is the even pace: with 9 of 30 days to go, 30% of the budget should remain. This service has 28%, so it is spending slightly faster than the window allows, and its current level sits just under the objective. That is amber, not red: there are still 12 minutes to spend.
Burn rate
| Window | Burn rate | Page at | Ticket at |
|---|---|---|---|
| 5 minutes | 16.2× | 14.4× | 6× |
| 1 hour | 14.9× | 14.4× | 6× |
| 6 hours | 3.1× | 6× | 3× |
| 3 days | 1.2× | n/a | 1× |
Code
<table class="burn">
<thead><tr><th>Window</th><th>Burn rate</th><th>Page at</th><th>Ticket at</th></tr></thead>
<tbody>
<tr><td>5 minutes</td><td class="n bad">16.2×</td><td class="n">14.4×</td><td class="n">6×</td></tr>
<tr><td>1 hour</td><td class="n bad">14.9×</td><td class="n">14.4×</td><td class="n">6×</td></tr>
<tr><td>6 hours</td><td class="n">3.1×</td><td class="n">6×</td><td class="n">3×</td></tr>
<tr><td>3 days</td><td class="n">1.2×</td><td class="n">n/a</td><td class="n">1×</td></tr>
</tbody>
</table>Burn rate is how fast the budget goes compared to an even pace: 1× spends exactly the budget over the window, 14.4× spends 2% of a 30-day budget in an hour. Pair a long and a short window so one bad minute does not page anyone; here both the 5 minute and 1 hour windows are over 14.4×, so this pages.
Budget states
Code
<div class="budget"><div class="budget-row"><span>search-api latency</span><b>82%</b></div><div class="budget-bar" style="--v:.82;--at:.4"><i></i><b></b></div></div>
<div class="budget"><div class="budget-row"><span>checkout-api availability</span><b>28%</b></div><div class="budget-bar warn" style="--v:0.280;--at:0.300"><i></i><b></b></div></div>
<div class="budget"><div class="budget-row"><span>ledger-writer freshness</span><b>0%</b></div><div class="budget-bar down" style="--v:0;--at:.6"><i></i><b></b></div></div>| Class | On | What it does |
|---|---|---|
.slo | section | The card: head, figures, budget, chart. |
.slo-head | header | Name and the objective in mono, a .badge on the right. |
.slo-figs | dl | A row of figures split by hairlines. dd.warn and dd.bad colour a value; a <small> adds its unit. |
.budget / .budget-row | div | Label and value above the bar. |
.budget-bar | div | --v is the budget left, 0 to 1. Green by default, .warn, .down. An inner <b> at --at marks the even pace. |
.burn | table | Burn rate per window against alert thresholds. td.n for numbers, td.bad over a threshold. |
- Write the objective as a sentence: "99.9% of requests succeed over 30 days."
- Show minutes next to percentages. 0.1% of 30 days is 43 minutes; people can reason about minutes.
- Turn the bar amber when it falls below the even pace, red when it is gone.
- An objective of 100%. There is no budget to spend, so every deploy is a violation.
- Paging on a single short window.
- Excluding planned maintenance after the fact. Decide what counts before the window starts.
Accessibility
- The bar's value is always printed next to it. If it stands alone, give it
role="meter"witharia-valuenow. - The burn-down is one image; say how much is left and when it was spent in its label.