do-incident-runbook
When to use
You need an on-call runbook for a service, are turning tribal knowledge into a document a tired responder can follow at 3am, or are capturing what to do when a specific alert fires.
Not for: defining the alerts or SLOs themselves (use do-observability), the planned release/rollback procedure (use do-release-checklist), or debugging cluster internals (use do-kubernetes).
Method
- State the service's purpose, owners, dependencies, and criticality up front, plus links to dashboards, logs, and deploy history.
- For each known failure mode, write a symptom -> diagnosis -> mitigation entry: the alert or user report, the exact commands/queries to confirm the cause, and the ordered steps to mitigate.
- Lead with mitigation over root cause. Decision: if service is down, restore first (roll back, scale out, failover, drain, flag off), then investigate — never debug a live outage before stabilizing it.
- Include escalation: when to page the next tier, who owns each dependency, and the severity ladder with response-time expectations. Decision: escalate when a mitigation fails or the blast radius grows, not after an arbitrary delay.
- Add safety rails: mark destructive commands, changes needing a second approver, and the rollback for each mitigation.
- Keep it current: reference the last incident, note gaps, and prompt the reader to update the runbook after use.
Example
### Symptom: checkout 5xx rate > 5% (alert: CheckoutErrorBudgetFastBurn)
Confirm:
- dashboard: https://grafana/checkout (error rate panel)
- recent deploy? `kubectl rollout history deploy/checkout`
Mitigate (in order):
1. If a deploy shipped < 30m ago -> roll back:
`kubectl rollout undo deploy/checkout` [safe, reversible]
2. If DB saturated -> scale read replicas (see db runbook).
3. Still failing after 10m -> escalate to Tier 2 (@payments-oncall).
Do NOT: flush the Redis cache — cold cache amplifies the outage. [DESTRUCTIVE]
Pitfalls
- Leading with root-cause analysis while the service is down — the responder debugs while users bleed instead of restoring first.
- Vague steps ("check the database") instead of the exact command/query a half-awake responder can paste.
- No escalation trigger, so an overwhelmed responder struggles alone past the point they should have paged.
- Unmarked destructive commands (cache flush, data delete) with no "do not / needs approval" rail.
Output format
Header: service | owners | dependencies | dashboards | severity ladder.
Per failure mode:
### Symptom: <alert or user report>
Confirm: <exact commands/queries>
Mitigate (in order): 1... 2... 3...
Escalate when: <trigger> -> <who>
Do NOT / needs approval: <destructive steps>
Post-incident: update-this-runbook checklist.
1---2name: do-incident-runbook3description: Produce a clear on-call runbook mapping symptoms to checks and mitigation-first steps so a tired responder acts fast and safely.4---56# do-incident-runbook78## When to use910You need an on-call runbook for a service, are turning tribal knowledge into a document a tired responder can follow at 3am, or are capturing what to do when a specific alert fires.1112**Not for:** defining the alerts or SLOs themselves (use do-observability), the planned release/rollback procedure (use do-release-checklist), or debugging cluster internals (use do-kubernetes).1314## Method15161. State the service's purpose, owners, dependencies, and criticality up front, plus links to dashboards, logs, and deploy history.172. For each known failure mode, write a symptom -> diagnosis -> mitigation entry: the alert or user report, the exact commands/queries to confirm the cause, and the ordered steps to mitigate.183. Lead with mitigation over root cause. Decision: if service is down, restore first (roll back, scale out, failover, drain, flag off), then investigate — never debug a live outage before stabilizing it.194. Include escalation: when to page the next tier, who owns each dependency, and the severity ladder with response-time expectations. Decision: escalate when a mitigation fails or the blast radius grows, not after an arbitrary delay.205. Add safety rails: mark destructive commands, changes needing a second approver, and the rollback for each mitigation.216. Keep it current: reference the last incident, note gaps, and prompt the reader to update the runbook after use.2223## Example2425```markdown26### Symptom: checkout 5xx rate > 5% (alert: CheckoutErrorBudgetFastBurn)27Confirm:28 - dashboard: https://grafana/checkout (error rate panel)29 - recent deploy? `kubectl rollout history deploy/checkout`30Mitigate (in order):31 1. If a deploy shipped < 30m ago -> roll back:32 `kubectl rollout undo deploy/checkout` [safe, reversible]33 2. If DB saturated -> scale read replicas (see db runbook).34 3. Still failing after 10m -> escalate to Tier 2 (@payments-oncall).35Do NOT: flush the Redis cache — cold cache amplifies the outage. [DESTRUCTIVE]36```3738## Pitfalls3940- Leading with root-cause analysis while the service is down — the responder debugs while users bleed instead of restoring first.41- Vague steps ("check the database") instead of the exact command/query a half-awake responder can paste.42- No escalation trigger, so an overwhelmed responder struggles alone past the point they should have paged.43- Unmarked destructive commands (cache flush, data delete) with no "do not / needs approval" rail.4445## Output format4647```48Header: service | owners | dependencies | dashboards | severity ladder.4950Per failure mode:51### Symptom: <alert or user report>52Confirm: <exact commands/queries>53Mitigate (in order): 1... 2... 3...54Escalate when: <trigger> -> <who>55Do NOT / needs approval: <destructive steps>5657Post-incident: update-this-runbook checklist.58```