Hirestack
Hirestack
Chapter 8

SRE practices: SLOs, error budgets, incidents

📖 7 min read · 12 sections · May 2026

Why this matters

Staff engineers are responsible for systems' lifetime behaviour, not just their initial implementation. SRE practices are the discipline of running software reliably: defining what "reliable" means quantitatively (SLOs), trading reliability against velocity (error budgets), responding to failures (incident response), and learning from them (post-mortems).

The shift here is from "code that works" to "code that's known to work, in production, at 3am, when nothing seems quite right." That's a different skill.

SLIs, SLOs, SLAs — disambiguation

Internal SLOs are stricter than external SLAs. The SLO is what engineering targets; the SLA is what marketing/legal commits to.

Choosing the right SLI

Most teams over-instrument and pick the wrong SLIs.

Bad SLI: "CPU utilisation under 80%." This is a resource metric, not a user-experience metric. Users don't care about CPU; they care if their request succeeded.

Good SLI: "Fraction of requests to /checkout that complete in under 1 second with a 2xx status code." This directly measures user experience.

Pick SLIs that are user-facing. Categories that work:

How to pick the SLO threshold

Three approaches, all valid:

  1. Empirical: measure current performance, set SLO slightly below it. "We've been doing 99.5%; let's commit to 99.5%."
  2. User-driven: ask "what fraction of failures would users notice?" Set SLO to match.
  3. Business-driven: what reliability does the product require to function? A payment service might need 99.99%; an analytics dashboard might be fine at 99%.

Don't over-promise. 99.99% (52 minutes of downtime per year) is a different operational commitment than 99.9% (8.76 hours per year). Each "nine" you add roughly doubles operational cost. Most internal services should be 99.5% or 99.9%. Critical revenue paths might be 99.99%. 99.999% is essentially impossible for stateful, multi-component systems without massive investment.

Error budgets — the social contract

Error budget = 100% − SLO.

If your SLO is 99.9%, your error budget is 0.1% of requests. If you serve 1M requests/day:

The error budget is permission to take risks. If you've used 10% of your budget for the month, you can be aggressive with deploys and experiments. If you've used 90%, you should freeze risky changes and focus on reliability.

This is the SRE "social contract": product can push for features; SRE can push back when error budget is depleted. Without an error budget, this becomes a subjective argument; with one, it's a number.

Burn-rate alerting (modern best practice)

Naive alerting: alert when error rate exceeds some threshold. Two problems:

  1. Slow burns get missed: 1% error rate over a week silently depletes your monthly budget; never triggers a threshold alert.
  2. Fast burns alert too late: by the time you notice, the budget is spent.

Multi-window, multi-burn-rate alerting (from the Google SRE Workbook):

Burn rateWindowBudget consumed in windowSeverity
14.4×1 hour2% (would burn 30-day budget in 2 days)Page
6 hours5% (5 days to burn)Page
1 day10% (10 days to burn)Ticket
3 days10%Ticket

The shorter windows catch fast-burning catastrophes; the longer windows catch slow-burning chronic issues. Combine them and you alert at the right urgency.

Incident response — the operational pattern

An incident is any unplanned event that degrades or risks degrading the service. The discipline of responding is structured.

Roles

The response phases

  1. Detect: alert fires, or someone reports. Acknowledge.
  2. Assess severity: how many users affected? Revenue impact? Is it growing?
  3. Stabilise: stop the bleeding. Roll back the deploy, increase capacity, failover, etc. Mitigation BEFORE root-cause analysis. Get back to a safe state.
  4. Investigate: now figure out root cause. With the bleeding stopped, you have time to think.
  5. Fix: apply the durable fix.
  6. Communicate: keep stakeholders informed throughout. Status page, internal channels, post-incident.
  7. Post-mortem: within 48 hours, write up what happened and what changes.

The most important lesson: mitigate before you root-cause. The instinct is to fix the bug; the discipline is to first stop the damage. Roll back, scale up, failover — anything to restore service — even if you don't yet know why.

Blameless post-mortems

The standard format:

  1. Summary (one paragraph): what happened, impact, duration.
  2. Timeline: minute-by-minute, with timestamps and quoted messages. Don't sanitise.
  3. Impact: how many users, requests, revenue. Quantify.
  4. Root cause: 5 whys analysis. Or contributing factors if not a single root cause.
  5. What went well: detection speed, response, communication. Praise specific behaviour.
  6. What didn't go well: where the response failed or was slow.
  7. Action items: who, what, when. Tracked to completion.

Blameless means: focus on systems, not individuals. "Engineer X deployed broken code" is wrong framing; "the deploy pipeline allowed broken code through" is right. Blameless post-mortems aren't soft — they're harder. They demand systemic fixes, not human ones.

War story — Cloudflare's regex incident (2019)
Cloudflare deployed a new WAF rule with a regex that was catastrophically slow on certain inputs. CPU utilisation went to 100% across their global edge in 30 seconds. Most of the internet (sites behind Cloudflare) became unreachable for 27 minutes. Their post-mortem (publicly available, blog.cloudflare.com) is a masterclass: timeline minute-by-minute, root cause (the regex), contributing factors (deployment process didn't have a sufficient soak time, the rollout was global not incremental, kill-switch for WAF didn't exist), and concrete action items. Read it. Then read more public post-mortems — they're free education.

Toil reduction

Toil = manual, repetitive operational work that doesn't grow value over time. Examples: manually restarting a flaky service, manually rotating credentials, manually onboarding new users.

Google's SRE book sets a target: SRE teams should spend no more than 50% of their time on toil. The other 50% should be on engineering work that reduces toil.

How to identify and reduce:

  1. Log every operational task and its time cost.
  2. If a task repeats more than ~3 times, automate it.
  3. Build self-service: instead of "ask SRE to restart the service," let app teams restart their own.
  4. Build observability: most toil comes from "we don't know what's happening." Better dashboards reduce toil.

Runbooks

For every alert, there should be a runbook: "if this alert fires, do these steps." Linked from the alert message itself.

Good runbook structure:

  1. What the alert means (in plain English)
  2. Likely causes
  3. Diagnostic steps (dashboards to check, commands to run)
  4. Mitigation steps (specific commands, with safety notes)
  5. Escalation: who to involve if mitigation fails

Without runbooks, every page becomes a "figure it out under stress" exercise. With runbooks, on-call shifts are tolerable and knowledge spreads across the team.

Applied scenarios

Scenario: You're new to a team. Their alerts page on average twice a night. What's your first month's plan?
Audit every alert: when did it last fire, what was the cause, did action need to be taken? Categorise. Likely findings: (1) Many alerts that don't require action (false positives) — delete or de-tune. (2) Alerts that fire frequently with the same fix — automate the fix. (3) Alerts without runbooks — write them. (4) Alerts whose SLO mapping is unclear — define SLOs and use burn-rate alerting instead. Most teams' alert hygiene is terrible; cleaning it up is one of the highest-ROI moves a Staff engineer can make.
Scenario: Define an SLO for a user-facing search API.
SLI candidates: (a) fraction of queries returning 2xx in under 500ms; (b) fraction of queries returning relevant results (harder to measure — needs shadow testing or click-through analysis). Pick (a) for v1: simpler, measurable. SLO: 99.5% over 30 days for an internal mid-tier service; 99.9% if it's revenue-critical. Define what 4xx means — user typos are not "failures"; missing index/down-service errors are. Burn-rate alerts on top. Add a separate latency SLO if median user-experience matters: "95% of queries under 250ms."
Scenario: An engineer wants to be on-call but is anxious about it. How do you onboard them?
(1) Shadow shifts: they ride along with experienced on-call, observe handling, don't actually respond. Two-three weeks. (2) Reverse shadow: they're the responder, the senior is shadowing them as backup. (3) Solo with explicit backup: they're primary, with a "if anything looks weird, page X" escape hatch. Throughout, make sure runbooks are accessible and the alerting volume is manageable. Anxiety is often a signal that runbooks are inadequate or alert volume is high; fix those rather than steeling individual engineers.

Further reading

SRE practices