River
Y CombinatorBacked by Y Combinator
FREE TEMPLATE

SLO and Error Budget Template

Six documents and three sheets, including a register that puts what your service actually achieved beside every reliability number you have already promised.

Free download  ·  No account needed

You have already promised reliability numbers in four places: a customer agreement, a renewal slide, a runbook header, a dashboard panel title. They disagree with each other, and none of them was ever checked against what the service delivered. Google's SRE Workbook names the outcome of adopting one anyway. A target tighter than the service can currently reach leaves you permanently out of SLO and subject to your own error budget policy. That is how a policy comes to be suspended the first time it would stop a release.

A latency target written as a percentile is worse than unmeasured, because it reports a number. Prometheus documents that its quantile function interpolates across bucket boundaries somebody chose, and that an observation missing its boundary label is silently ignored. A quantile landing in the highest bucket returns the upper bound of the second highest one instead. A service whose slow requests all sit above the top finite boundary reports a flat, excellent number that cannot be breached, and a regression inside the unlabelled traffic moves nothing at all.

So the specification sheet carries three columns. One transcribes each promise exactly as it is written with where it came from, one holds trailing attainment from your own telemetry, and one classes the pair as enforceable now, aspirational, or not measurable at all. Percentile targets get a countable rewrite beside the original. Once a target holds, the alert review prunes what pages on it and the incident postmortem reports what the outage cost the budget.

Eight targets already promised, one that can be enforced

Every attainment figure, budget and burn rate here derives from the same ninety days of telemetry. Nothing was typed in by hand.

SLI Specification

Illustrative rows for a fictional grocery delivery company, Ashgrove.

ServiceIndicatorTarget, as writtenWhere it was writtenTrailing 90dClassRewritten as
CheckoutRequest success99.9%runbooks/checkout.md, line 499.94%enforceableno change needed
CheckoutRequest success99.99%2026 renewal deck, slide 1199.94%aspirationaltracked, no policy attached
Catalogue searchRequest latency, p99p99 under 800msGrafana panel titlereads exactly 500ms, every daynot measurable99.0% of searches faster than 250ms
Driver app APIRequest latency, p95p95 under 300msplatform wiki, Reliability page210ms over 61% of trafficnot measurable99.0% faster than 300ms, counted at the gateway
Order trackingData freshnessnear real timehelp centre article, published99.2% under 30s oldenforceable after rewrite99.0% of reads under 30 seconds old
Payments gatewayHost uptime99.95% uptimevendor status page, in our contract99.97% theirs, 99.71% oursmeasures the wrong thing99.5% of authorisations decided within 3s
Catalogue searchRequest success99.5% agreement, 99.9% dashboardmaster agreement sch. 2, and the dashboard99.87%conflictingone target chosen, the other recorded as the floor
Nightly settlementOutput correctnessnone written anywherenowherenot instrumentednot measurableproportion of seeded records producing the expected output

Three columns where most registers carry one. The transcription, the measurement, and how the two relate. A register with only a target column is asserting; the middle column is what makes a wrong promise findable before a customer finds it.

Row two is the same indicator as row one. Both numbers are written down, one of them in front of an enterprise customer, and trailing attainment misses it by a factor of six. Adopting it means permanent breach, so it is measured and excluded from the policy by name.

Of eight written targets, one is ready to carry a policy today. That ratio is normal on a first pass.

Attainment History

One row per month per indicator. Consumption, not attainment, is the column that decides anything.

ServiceMonthTargetAttainmentBudget consumedLongest eventPolicy triggered
Checkout2026-0499.9%99.97%31%4mno
Checkout2026-0599.9%99.91%89%1h 52mno
Checkout2026-0699.9%99.74%260%6h 09myes, freeze from the 19th
Checkout2026-0699.99% aspirational99.74%2,600%6h 09mno, aspirational by policy
Catalogue search2026-0599.9% dashboard, 99.5% agreement99.87%130% of one, 26% of the other22munclear, two targets
Order tracking2026-0599.0%unknownunknown, 19 days unmeasuredno, and that is the problem
Payments gateway2026-0499.5%99.62%76%48mno, 12m maintenance excluded
Catalogue search2026-05p99 under 800ms500ms, every day0%, none computableno, and it never will

May and June are the two rows worth arguing about. May met its objective by a tenth of a point and spent 89% of the budget inside two hours, so the service had seventeen days left and no capacity for any of them. A monthly attainment figure alone cannot tell that apart from a quiet month.

Order tracking is recorded as unknown, not as a pass. The freshness exporter stopped on the 8th. A gap in telemetry that reads as a clean month is the fastest way for an objective to stop meaning anything, and nothing else in the row would show it.

The last row has a perfect ninety-day record against a target that cannot be breached. That is the argument for the rewrite in one line.

Budget Consumption

Burn rate is the headline number. Consumed percentage is not.

ServiceBudget, 30dConsumedBurn rateWindowThresholdNotifyState
Checkout8,400 bad requests3,780 (45%)1.043 days1ticketwithin budget
Checkout8,400 bad requests168 in 1 hour (2%)14.41 hour14.4pagepaging now
Catalogue search155,000 bad requests7,750 in 6 hours (5%)66 hours6pagepaging now
Order tracking240,000 stale reads24,000 over 3 days (10%)13 days1ticketticket open
Driver app API4,200 bad requests2,940 (70%) in 20 hours351 hour and 6 hours14.4 and 6pagepaging now
Payments gateway216 minutes241 minutes (112%)1.523 days1ticketexhausted, freeze in effect
Checkout840, aspirational3,780 (450%)10.4none, by policyexhausted, no action
Nightly settlementno budgetnone possibleno indicator

A burn rate of one ends the window with exactly nothing left. Checkout sits at 1.04 and reads as fine at 45% consumed, which is why the rate belongs on the dashboard and the percentage does not.

The driver API row is the argument for two windows. Thirty-five times burn empties a thirty-day budget in twenty and a half hours. A single rule set at thirty-six would never fire on it, and the rate just under your only threshold is the rate that empties the budget before anybody looks.

The last row has every cell empty on purpose. It caused two of the last four incidents and a service missing from the sheet is one nobody asks about.

What's in the pack

01

SLI Specification

One row per indicator, carrying the target transcribed exactly as written next to trailing attainment, the class, and the countable rewrite where the original could not carry a policy.

02

Attainment History

One row per month per indicator, with what consumed the budget, the longest single event inside it, every exclusion named, and whether the policy actually triggered.

03

Budget Consumption

The current period's burn rate against thresholds derived from the budget rather than picked, with a fast window and a slow one, and what each of them notifies.

04

Error Budget Policy

What happens at half, all and twice the budget spent, which objectives are named as requiring no action, and who may suspend the whole thing.

05

Reading a Latency Target

Why a percentile is an interpolation rather than a measurement, read off the query engine's own documentation, and what to count instead.

06

Definition Standard

Indicators as counts over counts, the four classes an objective can hold, and the questions a team answers once about windows and exclusions.

07

Worked Example, Checkout Availability

One service from a first look at ninety days of history through the target, the budget, the policy trigger and both alert windows.

How to use it

  1. 1

    Open in River, or take it blank

    Send the pack your availability data inside River, or download the six documents and three sheets and work through them without an account.

  2. 2

    Transcribe every promise

    Each reliability number you have already written down goes in with its source, exactly as worded, before anything is computed against it.

  3. 3

    Measure before you commit

    Trailing attainment lands beside each promise, and every indicator gets a class: enforceable today, aspirational, not measurable, or measuring something a user never experiences.

  4. 4

    Set the thresholds

    The alert windows come out of the budget rather than being picked, and the policy says what happens at half, all and twice the budget spent.

Frequently asked questions

Is this template free?

Yes, and the download needs no account and no card. Edit with AI is the optional half: it reads the availability data you send, transcribes every target you have already promised somewhere, and puts the real number beside each one. Every other pack is in the template library.

What format are the downloaded files?

Six documents as Word files and three sheets as CSVs, in one zip. The sheets open in Excel, Numbers or Google Sheets with the columns already ordered, and the documents open in Word or Pages. Nothing needs converting, and no part of the pack depends on River to be readable.

Our p99 panel has read the same number for weeks. Is that a problem?

It means the metric is capped rather than the service being steady. A quantile landing in the highest bucket returns the upper bound of the second highest one, so a target above your top finite boundary can never be breached. Prometheus's own histogram guidance is why the rewrite counts requests over a threshold instead.

What do we do about a target a customer has already been shown?

Keep measuring it and stop enforcing it. An aspirational objective is tracked beside the real one and named in the policy as requiring no action, so the gap stays visible without putting the team in permanent breach. Disagreement about the budget arithmetic goes to a named person, which the reference error budget policy escalates to the CTO.

How many alerts does an error budget need?

More than one window. A single threshold misses the burn rate sitting just under it, so alerting on SLOs pairs a fast window that catches a collapse with a slower one that catches sustained degradation, and each of them notifies differently.

We only have one month of data. Is that enough?

Yes, to start. One month gives a trailing figure and a first target under it, and the register records how long the period actually was rather than describing thirty days as ninety. Each further month becomes a row in Attainment History, and the quarterly review is where the number tightens.

How does this relate to our incident work?

An objective decides what counts as bad enough to page on, which is upstream of everything else. The runbook set covers responding to what pages, the incident timeline reconstructs what happened, and any architectural change the budget forces gets its own decision record. Whether the responder is handed a current document at all is the on-call handbook.

Find out which targets your service can actually hold

Take the Word documents and CSV sheets blank, or open this exact pack in River and let it measure the ninety days you already have.

Edit with AI