Incident postmortem template: a blameless format your team will actually finish
A copy-paste blameless postmortem template with a filled example, a 30-minute meeting agenda, a fast way to build the timeline, and where to store it.
The KnowWhyy team · · 6 min read
The incident is over, the graphs are green, and everyone wants to get back to work. Two weeks later the postmortem is still a half-filled doc with a timeline that stops at "investigating," three action items without owners, and nobody quite sure where the file lives. Six months after that, the same failure happens again and someone asks, "didn't we have an incident like this before?"
Here is a blameless template you can paste in today, a filled example, a short meeting format, a fast way to rebuild the timeline from Slack and GitHub, and the habits that get action items done.
What a postmortem is for
The Google SRE book defines a postmortem as a written record of an incident, its impact, the actions taken to mitigate or resolve it, the root causes, and the follow-up actions to prevent it from recurring. Atlassian's incident handbook uses almost the same four parts.
Two ideas from those sources shape everything below:
Decide the triggers before the incident. Google lists common triggers such as user-visible downtime beyond a threshold, any data loss, on-call intervention like a rollback, resolution time above a threshold, and a monitoring failure. Atlassian requires postmortems for severity 1 and 2 incidents and makes them optional otherwise. Pick your own rule and write it down, so nobody has to argue about whether this one "counts."
Blameless means you fix systems, not people. Google's chapter says a blameless postmortem assumes everyone "had good intentions and did the right thing with the information they had." Atlassian puts the key question well: not "why did individual x do this," but why the system allowed it or made it look like the right thing to do. In practice, Atlassian refers to people by role ("the on-call payments engineer") rather than by name in the write-up.
Ask your first question in minutes.
Create a workspace, connect a tool and choose what gets indexed. The free plan includes GitHub, Slack and Notion.
This combines the sections from Google's example postmortem with the fields Atlassian uses (detection, response, recovery, recurrence). Paste it as Markdown into your repo, Notion or Confluence.
# Postmortem: <short description> (<YYYY-MM-DD>)
Status: Draft | In review | Final
Severity: SEV-<n>
Incident owner: <name> Postmortem owner: <name>
Incident channel: <link> Incident ticket: <link>
Approver(s): <names>
## Summary
Two to four sentences. What broke, for whom, for how long, and how it was fixed.
## Impact
- Who was affected and how (users, internal teams, customers on plan X)
- Duration of impact: <start UTC> to <end UTC> (<n> minutes)
- Numbers: error rate, failed requests, support tickets, revenue or SLO budget used
## Detection
How did we find out? Alert, customer report, or someone noticing?
How long from start of impact to detection? How could we halve that?
## Response and recovery
Who responded and when. What we tried, what worked, and how we knew it worked.
Any delays (missing access, wrong person paged, unclear runbook)?
## Root causes and trigger
- Trigger: the change or event that started it
- Root causes: the conditions that let the trigger cause this much damage
- Recurrence: has this root cause caused incidents before? Links.
## Timeline (all times UTC)
| Time | Event | Source |
| ---- | ----- | ------ |
| HH:MM | ... | <link to PR, deploy, graph or Slack message> |
## What went well
## What went wrong
## Where we got lucky
## Action items
| Action | Type | Owner | Ticket | Due |
| ------ | ---- | ----- | ------ | --- |
| <verb + specific, bounded outcome> | Prevent / Detect / Mitigate / Process | <name> | <link> | <date> |
## Supporting links
Dashboards, logs, related postmortems, design docs, runbooks.
Keep "Where we got lucky." It names what would have made this incident much worse, which is often the next incident.
A filled example
This is a hypothetical incident, written the way a finished postmortem should read.
# Postmortem: Checkout API errors after connection pool change (2026-10-14)
Status: Final
Severity: SEV-2
Incident owner: on-call platform engineer Postmortem owner: Priya N.
Incident channel: #inc-2026-10-14-checkout Incident ticket: INC-482
## Summary
For 38 minutes, about 30% of checkout requests failed with HTTP 500.
A config change lowered the database connection pool size for the checkout
service. Under the afternoon traffic peak, requests waited for connections
and timed out. Rolling back the config restored service.
## Impact
- 14:12 to 14:50 UTC (38 minutes)
- Checkout error rate peaked at 31%; ~4,100 failed checkout attempts
- 37 support tickets; monthly checkout SLO budget: 42% used by this incident
## Detection
The "checkout 5xx rate > 5% for 5m" alert paged at 14:18, six minutes after
impact began. The alert worked as designed. A pool-saturation alert would
have caught it at deploy time, before the traffic peak.
## Response and recovery
The on-call engineer acknowledged at 14:20 and checked recent deploys at 14:27.
The config change wasn't in the deploy list because config ships through a
separate pipeline. The engineer found it at 14:41 by searching #deploys.
Rollback finished at 14:48; errors cleared by 14:50.
## Root causes and trigger
- Trigger: PR #2291 reduced pool size from 40 to 10 to cut idle connections.
- Root causes: config changes skip the canary stage; no alert on pool
saturation; config deploys don't appear in the deploy dashboard.
- Recurrence: none found.
## Timeline (all times UTC)
| Time | Event | Source |
| ----- | ----- | ------ |
| 13:55 | PR #2291 merged (pool size 40 -> 10) | GitHub PR #2291 |
| 14:02 | Config pipeline applies change to all regions | Actions run 9912 |
| 14:12 | Checkout 5xx rate starts rising | Grafana panel |
| 14:18 | 5xx alert pages on-call | PagerDuty incident |
| 14:27 | Recent app deploys checked; none in last 6h | Slack |
| 14:41 | Config change found in #deploys | Slack |
| 14:44 | Rollback of #2291 started | GitHub PR #2293 |
| 14:50 | Error rate back to baseline; impact ends | Grafana panel |
## What went well / went wrong / got lucky
- Well: alert fired within 6 minutes; rollback was a one-click revert.
- Wrong: config changes are invisible in the deploy dashboard.
- Lucky: the change landed before the evening peak, about twice as busy.
## Action items
| Action | Type | Owner | Ticket | Due |
| ------ | ---- | ----- | ------ | --- |
| Route config changes through the canary stage | Prevent | Priya N. | PLAT-901 | 2026-11-04 |
| Add alert: checkout pool wait time p95 > 200ms for 5m | Detect | Sam K. | PLAT-902 | 2026-10-28 |
| Show config deploys on the deploy dashboard | Mitigate | Lee W. | PLAT-903 | 2026-11-11 |
| Add "check config pipeline" step to checkout 5xx runbook | Process | Sam K. | PLAT-904 | 2026-10-21 |
The example names a PR and a pipeline as the trigger, not a person. The author of PR #2291 made a reasonable change; the system let it reach every region without a canary.
Build the timeline from Slack and GitHub
The timeline is the part people dread. Atlassian's blameless guide recommends building it first, so everyone agrees on what happened before debating why. PagerDuty's postmortem process says the same, and asks that each timeline entry have a supporting source such as a graph, a log search or a post.
You can rebuild most of it in 20 minutes from two places.
Slack. Open the incident channel and read it top to bottom; it is your raw log. Then search the surrounding channels for the same window using Slack's search modifiers:
in:#deploys on:2026-10-14 what shipped that day
in:#inc-2026-10-14-checkout the full incident log
checkout on:2026-10-14 -in:#inc-2026-10-14-checkout
early reports in other channels
For each useful message, copy the link to the message and paste it into the Source column. Links survive long after people forget the details.
GitHub. Find every change that landed shortly before impact. The merged: qualifier accepts date and time ranges:
# PRs merged in the six hours before impact
gh pr list --repo acme/checkout --state merged \
--search "merged:2026-10-14T08:00:00Z..2026-10-14T14:15:00Z" \
--json number,title,mergedAt,url
# Deploy workflow runs that day
gh run list --repo acme/checkout --workflow deploy.yml \
--created 2026-10-14 --json displayTitle,createdAt,conclusion,url
# Commits by date, if you merge without PRs
gh search commits --repo acme/checkout --committer-date=2026-10-14
Use one time zone (UTC is easiest) and mark four moments: start of impact, detection, mitigation and end of impact. The gaps between them are where most action items come from.
Run the postmortem meeting in 30 minutes
A good meeting confirms facts and agrees on actions. It does not rewrite the doc live. PagerDuty schedules the meeting within 3 calendar days for a SEV-1 and 5 business days for a SEV-2, shares the draft in Slack about 24 hours before, and keeps the meeting to 15 to 30 minutes.
Blameless postmortem: <incident title> (30 min)
Pre-read: <link to draft>, shared 24h before
1. (2 min) Reminder: this is blameless. We discuss systems, not people.
2. (8 min) Walk the timeline. Correct anything wrong or missing.
3. (8 min) Root causes. Ask "why" until the answer is something we can change.
4. (8 min) Actions: "What would prevent or shorten this class of incident?"
5. (4 min) What went well, what went wrong, where we got lucky.
Invite the responders, the owning team and one person from each affected team.
Action items that actually get done
Unfinished action items are why the same incident comes back. Three rules help.
Word them so they can be finished. Atlassian's handbook uses guidance from Google's Sue Lueder and Betsy Beyer: each action should be actionable (starts with a verb and produces an outcome), specific (narrow scope) and bounded (you can tell when it's done).
Instead of
Write
Investigate monitoring for this
Add alert when checkout pool wait p95 > 200ms for 5m
Fix config deploys
Route config changes through the canary stage
Be more careful with pool sizes
Add a CI check that rejects pool size below 20 for checkout
Track them where real work lives. Every action becomes a ticket in the owning team's backlog, linked from the postmortem. Atlassian tracks all postmortem actions in Jira and gives root-cause "priority actions" an SLO of 4 or 8 weeks depending on the service, with reminders and reports. PagerDuty warns against ticket sprawl and generally creates tickets only for P0 and P1 work. Fewer, finished actions beat a long list nobody touches.
Review them on a schedule. Add five minutes to an existing weekly meeting for overdue postmortem actions. Atlassian has managers regularly review a report of incidents whose root causes are not yet fixed.
Store postmortems where people will find them
Google's chapter says an unreviewed postmortem "might as well never have existed," and once reviewed, it goes into a team or organization repository of past incidents. Atlassian goes further and turns approved postmortems into internal blog posts. Whatever you choose, make it one place.
Option
Good for
Watch out for
postmortems/ folder in a repo
Engineering-only teams; reviewed by PR
Harder for support and product to read
Notion or Confluence database
Mixed audiences; filter by service and severity
Pages drift if nobody owns the space
Incident tool's built-in postmortems
Teams already using one for response
Export and search can be limited
Three habits make any of them searchable later:
Consistent file names and titles:2026-10-14-checkout-api-errors.md, with date first so they sort.
A few tags: service, severity, root-cause category. Atlassian groups root causes as bug, change, scale, architecture, dependency and unknown, which makes "how many config incidents this year?" answerable.
Links both ways. Link the postmortem from the incident channel, the fix PRs and the runbook it changed. Link those back from the postmortem. Then whichever artifact someone finds first leads to the others. See the runbook template for the runbook side, and how to find old decisions in Slack for the same idea applied to decisions.
Where KnowWhyy fits
The raw material for a postmortem already lives in Slack threads and GitHub PRs, and months later the hard part is finding it again. KnowWhyy indexes the GitHub repos and Slack channels you choose (private incident channels only after you invite the app), plus your Notion pages if postmortems live there. You can ask in the web app "what changed in the checkout service before the October 14 incident?" or "have we had connection pool incidents before?" and get an answer that links to the PRs, threads and pages it used, or a plain "not found" if the sources don't say. It doesn't replace writing the postmortem. It makes the old ones, and the context around them, easier to find. See GitHub history search or start free.
The short version
Agree on postmortem triggers before incidents happen, and keep every write-up blameless: systems and roles, not names.
Use one template with summary, impact, detection, response, root causes, timeline, lessons and action items.
Build the timeline first, from the incident channel, in:#deploys on:<date> in Slack and gh pr list --search "merged:<range>" in GitHub, with a source link on every row.
Keep the meeting to 30 minutes with a pre-read, and spend it on facts and actions.
Write actions that are actionable, specific and bounded, ticket them in the owning team's backlog, and review overdue ones weekly.
Store postmortems in one place with dated names, tags and links to the fix PRs and runbooks.