Openbook

Runbooks: Documentation That Works at 3 AM

How to write runbooks that hold up during real incidents: anatomy, templates, testing methods, on-call integration, and post-incident updates.

Knowledge & DocumentationOpenbook Team15 min read

It is 3:14 AM. The payments queue is backed up, the on-call engineer has been awake for ninety seconds, and the runbook she just opened begins with "First, familiarize yourself with the architecture of the billing subsystem."

That runbook has already failed. Not because the information is wrong, but because it was written for a reader who does not exist: a calm, caffeinated, fully-context-loaded engineer with an hour to spare. The actual reader is stressed, half-asleep, possibly new to the team, and needs to know exactly one thing: what do I type next?

This post is about writing runbooks for the reader who actually shows up at 3 AM. We will cover what belongs in a runbook and what does not, a template you can copy today, how to test runbooks before an incident tests them for you, how they fit into on-call rotations, and the maintenance loop that keeps them from rotting.

What a runbook is (and what it is not)

A runbook is a step-by-step procedure for handling a specific operational situation. That definition sounds obvious, but most documents labeled "runbook" are actually something else wearing a runbook costume. Sorting this out matters, because each document type has a different reader, a different moment of use, and therefore a different structure.

Document Reader's state Question it answers Failure mode when confused with a runbook
Runbook Stressed, mid-incident "What do I do right now?"
Architecture doc Calm, learning "How does this system work?" On-call reads theory while the queue grows
Post-mortem Calm, reflective "What happened and why?" History lesson instead of instructions
SOP Calm, doing routine work "How do we do this recurring task?" Missing urgency cues, no escalation path
Troubleshooting guide Curious, diagnosing "What might be wrong?" Open-ended exploration when you need a decision

The boundary that trips teams up most is runbook versus SOP. Both are procedural. The difference is the situation: an SOP covers planned, recurring work (rotating credentials quarterly, provisioning a new hire's accounts), while a runbook covers responsive work triggered by something going wrong or a time-sensitive operational event. If your document needs an escalation path and a "how do you know it worked" check, it is a runbook. If it can wait until after lunch, it is an SOP — and we have a separate guide on lightweight SOPs for small teams for that.

A useful test: could someone follow this document correctly while a Slack channel fills with question marks behind them? If the answer is no, it is not a runbook yet.

One scenario per runbook

Resist the urge to write "The Big Payments Runbook" that covers every possible payments problem. Multi-scenario documents force the 3 AM reader to do diagnosis and navigation at the same time. Write one runbook per alert or per failure scenario: "Payments queue depth exceeds 10k," "Payment provider webhook failures," "Database failover for the billing cluster." Small, single-purpose documents are easier to find, easier to test, and easier to keep current. If several runbooks share setup steps, link to a shared prerequisites page rather than duplicating or merging.

The anatomy of a runbook that works

Every effective runbook we have seen — across startups, agencies, and large platform teams — converges on the same eight sections. The order matters as much as the content, because it mirrors the order in which a responder needs information.

1. Title that matches the alert

The title should be the words the responder will search for or the alert will link to. "Payments queue depth exceeds threshold" beats "Queue management procedures." If the alert is named payments_queue_depth_high, put that exact string in the title or the first line. Findability at 3 AM means matching the reader's query, not the author's taxonomy — a principle that applies to all documentation, and one we explore in our guide to search and findability.

2. Symptoms and confirmation

Two or three bullet points that let the responder confirm they are in the right document: what the alert looks like, what users are reporting, what the dashboard shows. This section prevents the most expensive runbook failure — confidently executing the wrong procedure. Include a "you are NOT in this scenario if..." line when two failure modes look similar:

You are NOT in this scenario if the queue depth is high but consumer lag is zero — that is a producer spike, see the "Payments traffic surge" runbook instead.

3. Severity and blast radius

One or two sentences: who is affected, what breaks downstream, and how urgent this actually is. "Customer-facing checkout is degraded; every minute of backlog adds roughly one minute of payment delay" tells the responder whether to wake someone up. Without this, every incident feels maximally urgent, and responders either over-escalate (burning trust) or under-escalate (burning customers).

4. Prerequisites

Access, tools, and credentials needed — with links, not descriptions. "You need production read access to the billing cluster (request here if missing) and the ops CLI (install instructions here)." Discovering at step 6 that you lack a permission adds twenty minutes to every incident. List prerequisites up front so the responder can start access requests in parallel with reading.

5. Steps, with expected output after every command

This is the core, and it is where most runbooks fail. Three rules:

  • Exact commands, copy-pasteable. Not "check the queue depth" but the literal command with real flag values. Placeholder values in ANGLE_BRACKETS with a note on where to find the real value.
  • Expected output after every step. The responder needs to know they are still on the happy path. "You should see state: draining within 30 seconds. If you see state: stuck, go to step 9."
  • Decision points as explicit branches. "If X, do A. If Y, do B. If neither, escalate (see below)." Never "use your judgment" — at 3 AM there is no judgment, only pattern matching.

Number every step. Responders relay progress in incident channels ("I'm on step 4"), and numbers make hand-offs between responders possible mid-incident.

6. Verification

How do you know it worked? A specific check with a specific threshold: "Queue depth below 100 and holding for 5 minutes on this dashboard." Many incidents get extended because a responder assumed a fix worked, closed the incident, and got paged again forty minutes later. Verification is a step, not a vibe.

7. Escalation

Who to wake up, in what order, with what information. Name roles, not people ("current billing on-call — schedule here"), and state the threshold for escalating: "If step 5 does not resolve the backlog within 15 minutes, page the secondary." An explicit escalation threshold removes the worst on-call dilemma — "am I allowed to wake someone up for this?" The answer should be written down before anyone has to ask it at 3 AM.

8. Rollback and cleanup

If the procedure involves changing anything, document how to undo it, and list post-incident cleanup: scaling temporary capacity back down, removing feature flags, deleting debug logging. Temporary mitigations have a way of becoming permanent architecture when the cleanup steps are not written down.

A template you can copy today

Here is the full skeleton in Markdown. Copy it, delete what a given scenario does not need, but be honest about why you are deleting it.

# Runbook: [Exact alert name or scenario]

**Last verified:** 2025-08-12 by @name
**Owner:** Billing team
**Severity:** SEV-2 — checkout degraded, no data loss

## Symptoms
- Alert `payments_queue_depth_high` firing
- Dashboard [link] shows queue depth > 10,000
- NOT this scenario if consumer lag is 0 — see [other runbook]

## Blast radius
Checkout payments are delayed ~1 minute per minute of backlog.
No data loss. Refunds unaffected.

## Prerequisites
- Production read access to billing cluster ([request](link))
- `ops` CLI v2+ ([install](link))

## Steps
1. Confirm consumer health:
   `ops consumers status --service payments`
   Expected: at least 3 consumers in `state: running`.
   If fewer than 3 → go to step 4.
2. Check for poison messages:
   `ops queue inspect payments --head 5`
   Expected: messages parse cleanly.
   If a message errors → go to step 6.
3. Scale consumers:
   `ops consumers scale payments --count 6`
   Expected: queue depth falling within 5 minutes. → Verification.
4. Restart dead consumers:
   `ops consumers restart payments`
   Expected: `state: running` within 60 seconds. → step 1.
5. ...
6. Quarantine poison message:
   `ops queue quarantine payments --id MESSAGE_ID`
   (MESSAGE_ID from step 2 output) → step 1.

## Verification
Queue depth < 100 and stable for 5 minutes on [dashboard].
Checkout success rate back above 99% on [dashboard].

## Escalation
No improvement 15 minutes after step 3 → page billing
secondary on-call ([schedule](link)). Include: queue depth,
steps completed, links to output.

## Rollback / cleanup
- Scale consumers back: `ops consumers scale payments --count 3`
- File a ticket for any quarantined messages (they contain
  real customer payments).

Notice the header block: last-verified date, owner, severity. Those three lines do more for trust than anything else in the document. A responder who sees "last verified 14 months ago" knows to treat the commands skeptically; a responder who sees last month's date can move fast.

Writing for the degraded brain

Runbook prose has its own style rules, and they differ from normal documentation style because the reader is cognitively degraded. Stress narrows attention, working memory shrinks, and reading comprehension drops. Write accordingly.

Front-load the verb. "Restart the consumer with ops consumers restart payments" beats "The consumer can be restarted by running..." Imperative mood, every step.

One action per step. "Scale the consumers and then check the dashboard and if it looks okay silence the alert" is three steps pretending to be one. Steps that bundle actions get half-executed.

Ban ambiguity words. "Should," "may," "typically," "usually," and "as appropriate" are all ways of saying "the author did not decide." Every "usually" in a runbook is a question the responder now has to answer under pressure. If behavior genuinely varies, write the branch: "If X, then A; if Y, then B."

Never say "simply" or "just." If it were simple, there would be no runbook. When the step fails — and at 3 AM, steps fail — "simply" turns confusion into self-doubt.

Write the scary parts louder. If step 7 is destructive or irreversible, mark it visually before the command, not after:

⚠️ Destructive. This drops in-flight messages. Only proceed if step 6 confirmed the messages are duplicates.

Prefer links to explanations. The runbook is not the place to explain why the queue exists. Link to the architecture doc for the curious reader at 2 PM; keep the 3 AM path clean. A good rule: explanation goes in a one-line "why" note only when knowing the why changes how you execute the step.

The dialogue test

Read your draft aloud as if you were dictating it to a smart colleague from another team over the phone. Everywhere you would have to interrupt yourself to add context ("oh, and the staging flag is different, use --env prod"), the runbook is missing a line. This test takes ten minutes and catches more gaps than any review checklist.

Testing runbooks before an incident does

An untested runbook is a hypothesis. Teams routinely discover during real incidents that a command's flags changed two releases ago, a linked dashboard was deleted, or step 4 assumes access nobody on the current roster has. There are four testing methods, in increasing order of cost and confidence.

The new-hire read-through

Cost: 30 minutes. Hand the runbook to the newest person on the team and ask them to walk through it verbally, telling you what they would type and what they expect to happen. Every question they ask is a missing line. New hires are the best testers precisely because they lack the tribal context the author unconsciously assumed — the same context gaps we cover in capturing tribal knowledge.

The dry run

Cost: 1 hour. An engineer executes every non-destructive step against production for real — running the read-only commands, opening the dashboards, confirming the links resolve and the expected outputs match reality. Destructive steps are read aloud and sanity-checked but not executed. Do this on a rotation: one runbook per week per team keeps a library of 25 runbooks verified twice a year, and it doubles as on-call training.

The game day

Cost: half a day. Deliberately trigger the failure in a staging environment (or, for mature teams, in production with controls) and have the on-call engineer respond using only the runbook, while a facilitator takes notes on every hesitation, workaround, and improvisation. Game days find the deep problems: steps that work individually but conflict in sequence, verification checks that pass while the system is still broken, escalation contacts who no longer exist.

The real incident, instrumented

Every real incident is an unplanned runbook test — but only if someone captures the results. Make "did the runbook work?" a standing question in your post-incident review. Which steps were skipped? Where did the responder improvise? What did they Google mid-incident? Each improvisation is a patch the runbook needs. Our guide to blameless post-mortems and learning rituals covers how to run that review without turning it into a blame session.

A simple maturity ladder for a team's runbook practice:

Level State Typical experience at 3 AM
0 No runbooks Wake up the one person who knows
1 Runbooks exist, untested Runbook open in one tab, Slack archaeology in another
2 Read-through tested Steps mostly work; occasional stale command
3 Dry-run rotation Commands verified; incidents follow the script
4 Game days + post-incident patching Runbook is the script; escalations are rare and calm

Most teams sit at level 1 and believe they are at level 3. The dry-run rotation is the cheapest way to find out.

Runbooks in the on-call loop

A runbook that is not linked from the alert might as well not exist. The moment of need is the page itself, so the connective tissue matters:

Alert-to-runbook linking. Every alert definition should carry a link to its runbook. Make this a merge requirement for new alerts: no runbook link, no alert. An alert without a runbook is an instruction to panic.

Runbook-to-everything linking. From the runbook, one click to: the relevant dashboard, the escalation schedule, the incident channel, and the architecture doc. The responder should never need to remember where anything lives.

The 3 AM triage header. Some teams add a three-line box at the very top of every runbook: Can this wait until morning? Who is affected? What is the one-line fix if you have seen this before? Roughly a third of pages turn out to be "acknowledge, apply the known fix, sleep" — and letting responders confirm that in ten seconds is a genuine quality-of-life improvement for the rotation.

Hand-off notes. Long incidents outlive one responder's shift. Because steps are numbered, the outgoing responder can write a two-line hand-off: "Completed through step 5, queue draining slowly, escalate at 06:30 if depth still above 5k." Runbooks make hand-offs possible; without them, every hand-off is a 20-minute re-briefing.

Who writes the runbook?

The person who resolved the incident without a runbook writes the first draft — within 48 hours, while the improvised steps are still in their shell history. This is the single highest-payoff documentation rule for operations teams. The draft does not need to be polished; it needs to exist. Polish comes from the next dry run.

Keeping runbooks alive

Runbooks decay faster than almost any other document type because they encode implementation details — commands, flags, thresholds, dashboard URLs — that change with every release. A maintenance loop with four parts keeps them trustworthy:

Post-incident patching. The review's standing question ("did the runbook work?") produces a patch list, and patching the runbook is an action item with an owner and a deadline like any other. Teams that treat runbook updates as optional follow-up end up with runbooks that describe the system as it was three quarters ago.

Last-verified dates, enforced. The header's "last verified" date is a staleness signal for readers and a work queue for the team: anything older than six months goes into the dry-run rotation. Some teams automate a reminder when a runbook crosses the threshold.

Ownership by team, not person. "Owner: @jana" becomes a lie the day Jana changes teams. Assign runbooks to a team, and let the team's rotation handle verification. Individual names belong only in the "last verified by" field, as a record rather than a responsibility.

Delete bravely. A runbook for a decommissioned system is worse than no runbook — it shows up in search results at 3 AM and burns five minutes before the responder realizes it is describing dead infrastructure. When a system is retired, its runbooks get archived the same week. Findability is as much about removing wrong answers as providing right ones.

Common failure modes, diagnosed

Symptom Root cause Fix
"The runbook is out of date" heard mid-incident No post-incident patch loop Standing review question + patch action items
Responders skip the runbook entirely Past experiences of stale/wrong steps Dry-run rotation to rebuild trust; delete dead docs
Runbook found but wrong scenario executed Missing symptoms/confirmation section Add "you are NOT here if..." lines
Every incident escalates immediately No severity/blast-radius section Add explicit escalation thresholds
One giant document per system Author-centric organization Split to one runbook per alert/scenario
Steps work for the author only Assumed access and context New-hire read-through; prerequisites section
Fix applied, incident reopened an hour later No verification section Concrete verification thresholds with dashboards

If you recognize three or more of these, do not launch a "documentation initiative." Pick your five most-paged alerts, write or rewrite those five runbooks with the template above, and put them on a dry-run rotation. Five trustworthy runbooks beat fifty aspirational ones.

Where runbooks should live

The requirements fall out of everything above: plain-text authoring so engineers actually write them, Markdown so code blocks and tables render properly, fast search so the alert title finds the doc, tight linking so the runbook connects to dashboards and escalation schedules, and visibility for the whole team rather than a folder someone owns.

A wiki-style room with Markdown and live preview fits this exactly — in Openbook, teams typically keep runbooks in a Wiki room (GitHub-flavored Markdown, side-by-side preview) inside their engineering space, with a Q&A room next to it for the "why did this happen?" follow-up questions that runbooks deliberately leave out, and global search connecting alert names to documents. The pattern works in any toolchain; what matters is that the runbook, the questions, and the search live close together instead of scattered across three products. You can see how the room types compose on our features page.

A note on runbooks-as-code: some teams keep runbooks in the service's repository, versioned alongside the code they describe. This is a legitimate pattern with real benefits (runbook changes ride along with the PRs that invalidate them). Its weakness is findability for responders outside the owning team and for anyone not in an editor at 3 AM. A workable hybrid: author in the repo, mirror to the searchable knowledge base automatically, and treat the repo as the source of truth.

Next steps

Runbooks are the rare documentation type with a measurable payoff: shorter incidents, calmer rotations, fewer 3 AM escalations to the one person who knows everything. Here is the four-week version of everything above:

  1. Week 1: List your ten most frequent alerts. Check which have runbooks linked. The gap is your backlog, ordered by page frequency.
  2. Week 2: Write the top three missing runbooks using the template. First drafts by whoever handled those incidents most recently.
  3. Week 3: Run a new-hire read-through on each. Patch every question they asked.
  4. Week 4: Add the merge rule (new alert → runbook link required) and the post-incident standing question ("did the runbook work?"). Start a weekly dry-run rotation.

Four weeks, no committee, no initiative — just five documents that will be there, correct and copy-pasteable, the next time the pager goes off in the dark.

If your team's runbooks are currently scattered across five tools, Openbook gives you a Wiki for the procedures, Q&A for the follow-up knowledge, and search that connects them — free to start, with all room types included, at openbook.work.

Keep reading

Knowledge & Documentation14 min read

Markdown for Teams: Why Plain Text Wins

Why Markdown beats rich editors for team documentation — portability, diffability, speed — plus an honest look at where block editors win instead.

May 15, 2026

Put these ideas to work

Openbook gives your team one home for feeds, boards, docs, check-ins and more — free to start.