The test a runbook has to pass
Hand it to someone competent who has never seen the system, take away their ability to ask you anything, and give them a failure. If they can work out what broke and what to do about it, the runbook works. If they cannot, it is a description rather than a runbook.
Most automation documentation fails this test because it explains what the system does rather than what to do when it does not.
Start with the contract, not the diagram
Diagrams age badly and tend to describe an implementation that has since changed. What stays stable is the contract: what goes in, what comes out, and what is guaranteed.
State it plainly. This workflow accepts a submission with these fields. It guarantees the record is stored before the visitor sees a confirmation. It attempts delivery to these targets. It does not guarantee delivery on the first attempt. It retries transient failures up to this many times.
Someone reading that knows immediately whether a missing record and a missing email are the same problem. They are not, and that distinction is the whole of the debugging.
Name the trigger precisely
"Runs when a form is submitted" is not precise enough. Which form, on which page, posting to which endpoint, and is there a schedule as well? If there is a cron, state the expression and the timezone it is interpreted in — a cron written in UTC and read by someone in another timezone is a recurring source of "it did not run" reports when it ran exactly as configured.
Enumerate the failure modes you already know about
This is the section that earns the document. For each one: what it looks like from the outside, how to confirm it, and what to do.
- The upstream service is down — symptom, how to check, what to do, and whether it self-recovers
- A credential has expired — how it presents, where to renew, what to replay afterwards
- The input arrived in an unexpected shape — where the rejected payload is kept, how to reprocess
- The run did not fire at all — how to distinguish "did not fire" from "fired and did nothing"
That last one matters more than it looks. A run that fired and found nothing to do, and a run that never fired, are completely different problems with the same visible signature: nothing happened.
Say how to observe it
Where do the logs go, how long are they kept, and what is the one query that answers "did this run today". If observability is an execution history inside a hosted platform, say how long that history is retained, because that number decides whether investigating last week's incident is even possible.
If nothing notifies anyone on failure, write that down explicitly. A known gap is manageable. An assumed alert that does not exist is how failures go unnoticed for weeks.
Write down the recovery, including the manual one
Every automation should have a documented way to do the same work by hand. Not because you expect to, but because the day the platform is down is not the day to be reverse-engineering what the workflow was supposed to produce.
Include whether reprocessing is safe. If the workflow is idempotent, say so and say why — usually because of a key that makes a duplicate collapse into the original. If it is not idempotent, say what running it twice would do, because someone will eventually be deciding whether to press the button under time pressure.
Name an owner and a review date
An unowned automation degrades quietly. APIs change, credentials expire, volumes grow past a tier. Put a name against it and a date to look at it again, and keep the runbook next to the code rather than in a document nobody opens.
The runbook is not overhead on the build. It is the part that makes the build survivable.
Write it while building, not afterwards
A runbook written after the fact documents what you remember, which is the happy path. The awkward details — why that retry is three and not five, why that field is nullable, which upstream returns a 200 with an error body — are exactly the things that fade first and matter most.
Keeping a running note while building costs almost nothing and captures decisions at the moment there is a reason for them. Tidy it at the end.
Record what you decided not to do
A runbook that only describes the built thing invites the next person to "improve" it back into a problem you already solved.
If you deliberately did not retry a class of failure, say so and say why. If a step is manual on purpose because the cost of being wrong is high, write that down. These notes prevent a specific and frustrating kind of regression: someone removing a safeguard because its reason was never recorded.
Include the queries, not just the advice
"Check whether the sync ran" is advice. The exact query, with the table and the field, is a runbook.
Paste the commands. The log filter that shows this workflow's runs. The query that returns the last successful run. The call that re-triggers it. Someone debugging at an inconvenient hour should be copying and pasting, not reconstructing your reasoning.
Test the handover for real
The only reliable check is to have someone else use it. Pick a colleague, give them a deliberately broken staging environment and the runbook, and stay out of the conversation.
Everything they have to ask you is a gap. Write down the answer and the document improves permanently. Skip this and you have a document that is complete to its author, which is the only reader who did not need it.