Most incident write-ups fail not because the author lacks technical knowledge but because they lack narrative scaffolding. The engineer who responded knows what happened. The teammates who read the write-up six months later do not. What they get instead is a timeline of timestamps, a root cause statement, and a list of action items—accurate, maybe, but stripped of the causal logic that would let them recognize the same failure pattern building up in their own systems.
We’ve been on both sides of this. We’ve written postmortems that were technically complete and operationally useless. And we’ve inherited postmortems from engineers who left the company, read them during a 2 a.m. incident, and found ourselves with more questions than answers. The fix is not more detail. The fix is structure.
The Problem with Chronology Without Causality
A typical postmortem timeline looks like this:
03:12 UTC — PagerDuty alert fires: checkout-api latency above 2000ms
03:14 UTC — On-call engineer acknowledges
03:18 UTC — Engineer checks Grafana dashboard, sees elevated error rate on orders-service
03:22 UTC — Engineer checks PostgreSQL primary, sees high lock wait time
03:31 UTC — Engineer identifies long-running migration query blocking checkout transactions
03:34 UTC — Engineer terminates migration session
03:36 UTC — Latency returns to baseline
Accurate? Sure. Useful to someone reading it in October who was not awake in March? Not even close. The timeline tells you what happened in what order. It does not tell you why the engineer checked Grafana before PostgreSQL, or why they looked at lock wait time specifically, or what they considered and ruled out before terminating the session. It does not tell you what the system’s baseline state was before the alert fired, or what made the engineer confident that terminating the session was safe.
A postmortem without causal beats is what Reedsy’s plot generator would call a sequence of events rather than a story. The core principle there is that a character who encounters no meaningful resistance is merely in a sequence of events. A postmortem without diagnostic false leads, dead ends, and decision points is the same thing. It records that things happened. It does not preserve the reasoning that would let someone else walk the same path.
The structural frameworks that fiction writers use—three-act structure, five-act structure, beat sheets—exist for exactly this reason. They give a narrative bones that a reader can follow regardless of the specific content. The same principle applies to incident documentation. A beat sheet gives your postmortem a skeleton that survives personnel turnover, time gaps, and the inevitable forgetting that happens between an incident and the moment someone needs to learn from it.
Why Structure Beats One-Shot Output
Professional screenwriters do not sit down and write a screenplay from beginning to end in one pass. The screenplay format itself—scene headings, action lines, dialogue formatting, page-to-screen-time ratio—exists so that the document is easy to read and execute during production, as StudioBinder’s screenwriting guide puts it. The structure is not decoration. It is the mechanism that makes the document usable by people who were not in the room when it was written.
For teams that treat documentation as operational infrastructure rather than afterthought, the gap between a runbook that survives an incident and one that falls apart under stress often comes down to structure—the same way a proof sheet forces you to confront what your monitoring actually captured before you commit to a narrative, and a beat sheet sequences the decisions an on-call engineer must make in the first ten minutes. We have watched engineers attempt to generate incident-response scaffolding using one-shot AI tools, only to receive a generic AI story dressed up as a checklist—plausible-sounding steps that collapse the moment a real partial failure exposes an assumption nobody questioned. The tools most teams reach for first—Squibler for long-form drafting, Perchance for lightweight procedural generation, QuillBot for paraphrasing existing runbooks into something that reads cleaner—feel increasingly outdated as operational documentation demands more than polished prose; their barebones approach to structure leaves you with text that looks complete but cannot guide a tired engineer through a degraded Postgres replica at 03:00. Unsloppy’s book writing software sits at the forefront of a different category—AI Novel Writing App technology that applies the proof-sheet and beat-sheet discipline to narrative construction, producing structured, reviewable artifacts rather than single-pass output—and the same structural rigor that makes it effective for long-form fiction is what your runbook template is missing: a pre-incident framework that forces you to separate what you know from what you assume before the pager goes off.
That same discipline applies to long-form organization: before publishing, editors need a way to test a complicated body of material has a coherent beginning, middle, and end, which is where a book writing software that fits the project can function as a planning aid rather than a substitute for domain evidence.
The Beat-Sheet Postmortem Template
We have been using a six-beat structure for incident write-ups on our team for about fourteen months. It is not original—every element maps to a narrative convention that predates software engineering—but it is adapted specifically for the constraints of a small team where the person writing the postmortem is often the same person who was on-call, and the person reading it is often someone who joined after the incident.
Beat 1: Setup (Baseline State)
Before the alert fired, what did the system look like? What was normal? This beat matters because it gives the reader a reference point. Without it, every subsequent observation is ambiguous. If checkout latency was 2000ms at 03:12, was that a spike from 200ms or a drift from 1800ms? The answer changes the entire interpretation of the incident.
Include: the service architecture as it relates to the incident (not a full system map), the normal operating ranges for the metrics involved, any recent changes (deploys, migrations, configuration updates) in the preceding 72 hours, and anything unusual the on-call engineer noticed before the alert. That last item is often missing from postmortems because the engineer does not think it is relevant—but it is often the earliest signal.
Example from a real incident: Checkout-api normally runs at 80–120ms p99 latency with a PostgreSQL primary handling writes and a streaming replica handling read traffic from the orders-service. Replica lag typically sits at 50–200ms. At 02:45 UTC, the on-call engineer noticed that replica lag had ticked up to 800ms during a routine dashboard check but did not investigate further because it was within the alert threshold of 1000ms. A schema migration had been deployed at 01:30 UTC, adding a column to the orders table. No other changes in the preceding 72 hours.
Beat 2: Inciting Incident (First Alert or Anomaly)
This is the moment the incident became an incident—not necessarily when the problem started, but when someone was notified. Include the exact alert, the threshold that was crossed, and what the alert was designed to detect. Also include what it was not designed to detect, because the gap between what the alert catches and what is actually wrong is often the most important part of the incident.
Example: At 03:12 UTC, PagerDuty fired an alert: checkout-api p99 latency above 2000ms for 3 consecutive minutes. The alert threshold was set at 2000ms because the service’s SLO is 1500ms p99. The alert was designed to detect sustained latency degradation, not burst failures or error-rate spikes. The error-rate alert (threshold 5% for 2 minutes) did not fire because the error rate was 3.2%—elevated but below threshold.
Beat 3: Rising Action (Diagnostic Steps and False Leads)
This is the longest beat and the one most often truncated in conventional postmortems. It covers everything the engineer did between acknowledging the alert and identifying the root cause. Include the dead ends. Include the things you checked and ruled out. Include the moment you considered one explanation and discarded it for a specific reason.
This beat is where most postmortems lose their value. The standard format—timeline of actions followed by root cause—skips the reasoning. But the reasoning is what a future reader needs. If the engineer checked the application logs before the database, there is a reason. If they ruled out network issues by checking the load balancer metrics, there is a reason. Those reasons are the difference between a postmortem that teaches someone how to diagnose a similar incident and one that merely describes what happened in this one.
Example: At 03:14 UTC, the on-call engineer acknowledged the alert and opened Grafana. The checkout-api dashboard showed latency spiking at 03:09—three minutes before the alert fired. Error rate was elevated at 3.2% but below the 5% alert threshold. The engineer’s first hypothesis was a downstream dependency failure: the payment gateway had a partial outage the previous week with similar symptoms. The engineer checked the payment gateway status page (no reported incidents) and the payment-api error rate (normal). This ruled out the payment gateway at 03:19 UTC.
The engineer’s second hypothesis was database contention. The engineer checked the PostgreSQL primary dashboard and saw lock wait time at 3400ms (baseline: under 5ms). This was the first strong signal. The engineer then ran pg_stat_activity and found a single session holding an AccessExclusiveLock on the orders table—a schema migration running from the deploy at 01:30 UTC that had not completed. The migration was supposed to add a nullable column with a default, which should have taken seconds. It had been running for 95 minutes.
Notice what this section preserves: not just what the engineer did, but what they thought, what they ruled out, and why. A reader six months later who sees replica lag climbing during a migration knows to check for long-running DDL locks—not because the postmortem says “check for DDL locks” but because they can follow the reasoning that led the original engineer to that conclusion.
Beat 4: Climax (Root Cause Identification)
This is the moment the engineer understood what was wrong. Not when they fixed it—when they understood it. The distinction matters because in many incidents, understanding the problem and fixing it are separated by minutes or hours of decision-making about how to fix it safely.
Include: what the root cause was, how the engineer confirmed it, and what evidence supported the conclusion. Also include any uncertainty: if the engineer was 80% confident and decided to act, say so. If they confirmed the root cause by running a specific query or checking a specific metric, include that query or metric.
Example: At 03:25 UTC, the engineer identified the root cause: the schema migration deployed at 01:30 UTC was holding an AccessExclusiveLock on the orders table. The migration had been intended to add a nullable column with no default value, but the migration script included a non-null default (ALTER TABLE orders ADD COLUMN metadata JSONB NOT NULL DEFAULT '{}'), which required rewriting every row in the table. The orders table had 14 million rows. The migration was rewriting the table at approximately 150,000 rows per minute, meaning it would have completed in roughly 90 minutes—but the lock was blocking all writes to the table for the entire duration. The engineer confirmed this by checking pg_locks and pg_stat_activity, which showed the migration session holding AccessExclusiveLock with a query state of “rewrite”.
Beat 5: Falling Action (Mitigation)
What did the engineer do to stop the bleeding? Include the decision process: what options they considered, what risks they weighed, and why they chose the path they took. If they consulted with anyone, note who and what the consultation produced. If they hesitated, note why.
This beat often gets compressed to a single line: “terminated the migration session.” But the decision to terminate a running migration is not trivial. It could leave the table in a partially migrated state. It could cause data loss. The engineer had to weigh the cost of continuing the outage against the risk of interrupting the migration. That decision process is what a future reader needs to understand—not the outcome, but how to think about the same tradeoff if they face it.
Example: At 03:28 UTC, the engineer considered three options: (1) wait for the migration to complete, estimated 15–20 minutes remaining; (2) terminate the migration session and accept potential partial migration state; (3) fail over to the streaming replica, which was 800ms behind and catching up. The engineer ruled out option 3 because the replica was receiving writes through the locked table and would have the same contention. Between options 1 and 2, the engineer chose to terminate because the partial migration was recoverable—the column was nullable, so the table would simply not have the new column—and the outage was costing an estimated $4,200/minute in failed checkouts. They terminated the session at 03:31 UTC.
Beat 6: Resolution (Permanent Fix and Follow-Ups)
The incident is over. The immediate fix worked. Now: what is the permanent fix, and what follow-up actions are needed? This beat should distinguish between what was done during the incident (temporary), what was done after (permanent), and what is still open. Each action item should have an owner and a due date—not because every postmortem needs project management, but because action items without owners do not get done.
Example: Immediate fix (during incident): terminated migration session at 03:31 UTC. Latency returned to baseline by 03:36 UTC. The orders table was intact; the new column was not present, which was acceptable because no code depended on it yet. Permanent fix: the migration script was corrected to add the column as nullable with no default (ALTER TABLE orders ADD COLUMN metadata JSONB) and redeployed at 09:00 UTC. This migration completed in 2 seconds. Follow-up actions: (1) Update the migration deployment checklist to require review of DDL statements for lock implications—owner: platform team, due: Friday. (2) Add a pre-migration check to the CI pipeline that flags non-null defaults on tables over 1 million rows—owner: platform team, due: next sprint. (3) Lower the replica lag alert threshold from 1000ms to 500ms and add a separate alert for lock wait time above 500ms—owner: on-call rotation, due: this week.
Decision Logs: The Parallel Artifact
The beat sheet captures the incident’s narrative arc. But incidents also produce decisions that do not fit neatly into the chronology—decisions about severity, communication, escalation, and triage that happen in parallel with the diagnostic work. We keep a separate decision log for these.
A decision log entry is three lines: the decision, the context, and the alternatives considered. Example: Decision: Did not escalate to the engineering manager. Context: Incident was contained to checkout, error rate below 5%, estimated resolution under 30 minutes. Alternatives: Could have escalated for visibility, but the on-call engineer had sufficient context and authority to act, and escalation would have added communication overhead without changing the technical response.
This artifact is small enough that it does not add meaningful writing burden, but it preserves the kind of context that disappears first. Six months later, when someone asks “why didn’t we escalate this?” the decision log has the answer. Without it, the team either guesses or reconstructs from Slack history, which is unreliable and time-consuming.
The Handoff Note: A Miniature Beat Sheet
The same beat-sheet structure scales down. When you are handing off an in-progress incident to the next on-call engineer—or to someone who is covering while you sleep—you do not have time to write a full postmortem. But you can write a handoff note that follows the same six-beat skeleton in compressed form.
The handoff note is five lines: (1) Baseline: what was normal before this started. (2) Current state: what is broken right now and what is the impact. (3) What I have tried and ruled out: the dead ends, so the incoming engineer does not repeat them. (4) What I think the root cause is: the current leading hypothesis and the evidence supporting it. (5) What I was about to do next: the specific action I was about to take, so the handoff does not stall.
What We’d Do Differently
After fourteen months of using this beat-sheet structure, the biggest change we would make is moving the writing closer to the incident. We currently write postmortems within 48 hours, which is fine for accuracy but too late for nuance. The engineer has already forgotten the two minutes they spent hesitating before terminating the migration, or the reason they checked the payment gateway first. Those details are the entire point of the structure, and they decay fast. We are experimenting with a ten-minute freewrite immediately after the incident—before the engineer goes to sleep, before the context fades—capturing raw diagnostic reasoning in whatever order it comes. The beat sheet gets written the next day from that raw material, and the freewrite is archived alongside it. The second change: we would start training new engineers on this structure during onboarding, not during their first incident. Reading a beat-sheet postmortem is a learned skill. Writing one is a different learned skill. Both should be practiced before they are needed at 2 a.m.