A short, structured writeup of one incident. Focus: what happened, what the contributing factors were, what we're changing, and how we'd notice this faster next time. NO finger-pointing — the human who deployed at 4pm Friday is doing what the system allowed; the system is what we change.
When to use
- Anything where users noticed (latency, errors, missing data)
- Internal-only near-miss the team still wants to learn from
- Security incident (separate audit trail concerns; this is the engineering writeup)
Skip for: simple bug fixes that didn't reach prod, planned maintenance windows, single-customer issues with no systemic component.
Workflow
Timeline first, narrative second. Open a doc, fill the timeline before writing prose. Use UTC. Each entry: timestamp, who/what acted, what they observed. Start the timeline before the user-visible breakage (often the proximate cause was minutes-to-hours earlier than the alert).
Distinguish proximate, contributing, and root. Proximate: the one change/event that directly tipped things over. Contributing: the conditions that made the proximate change harmful (missing test, missing alert, recent unrelated change). Root: the systemic gap that let the contributing factors persist. Most outages have one proximate cause and 3-5 contributing factors. Be honest about the difference.
Action items get owners + dates. Every action item must have a name and a target date. "Add better monitoring" with no owner = will never happen. "@maya by 2026-06-15: add P95 latency alert on /skills" = real.
What went well. Yes, really. Detection time, response coordination, rollback worked, customer comms got out — name what worked so the team keeps doing it. Postmortems that only list failures train the team to dread them.
Detection delta. Did we notice from a user report or from telemetry? If user report, the action item is "build the telemetry that would have caught this." If telemetry, how fast was it?
Template
# <YYYY-MM-DD> <one-line title>
**Severity:** Sev1 | Sev2 | Sev3
**Owner:** <name> (writing)
**Status:** Resolved at <UTC time>
## Summary
<2–3 sentence executive summary. Skip the suspense.>
## Timeline (UTC)
- HH:MM — <what happened>
- HH:MM — <next event>
...
## Impact
- Users affected: <number, %, segments>
- Duration of user-visible impact: <minutes>
- Data integrity: <none lost | <quantified loss> | unknown>
- Customer comms: <sent / not sent>
## Contributing factors
1. <factor + brief why-it-mattered>
2. <factor>
3. <factor>
## What went well
- <thing>
- <thing>
## Action items
| # | Item | Owner | Target | Issue |
|---|---|---|---|---|
| 1 | <change> | <name> | <date> | <link> |
| 2 | <change> | <name> | <date> | <link> |
## Detection delta
<How we found out + how we'd find out faster.>
Definition of done
- Timeline in UTC, with at least one entry BEFORE user-visible breakage
- Impact quantified (users affected + duration + data)
- 3+ contributing factors named (not just "human error")
- Every action item has owner + target date
- At least one "what went well" item
- No names used pejoratively ("X deployed without testing" → "the deploy bypassed the test gate")
Gotchas
- "Human error" is not a contributing factor. It's a symptom. Why did the system rely on a human noticing this? Push deeper.
- Don't write the postmortem during the incident. Stabilize first, document second. A doc written while the bridge is on fire will be wrong about the timeline.
- Resist root-cause tunnel vision. Most outages have multiple contributing factors. "Database failed" is rarely the whole story; "database failed, alerts went to the wrong channel, the runbook was out of date, the on-call rotation had a gap" is closer.
- Action items should be testable. "Add monitoring" is bad. "Add an alert that fires when /healthz returns non-200 for 60s" is good — you can verify it shipped.
- Customer comms is part of the story. When did we tell users? What did we say? "We didn't" is a valid timeline entry and usually a meaningful action item.