Written by
Halkwinds Editorial Team
Halkwinds Research & Editorial

Engineering Documentation That Engineers Actually Read
How to write architecture docs, runbooks, and decision records that get used — with templates and a lightweight review process.
Every engineering manager has lived this scene: a senior engineer leaves, and three weeks later a production incident surfaces a service nobody fully understands. The onboarding doc is 18 months stale. The runbook points to a dashboard that was decommissioned last quarter. The architecture "diagram" is a Slack screenshot buried in a thread. Documentation debt is quieter than technical debt, but it compounds just as fast — and it usually gets paid off at the worst possible moment. The problem is rarely that engineers refuse to write. It's that most documentation is written for the wrong reader, at the wrong time, in the wrong format, and with no process to keep it honest. This article lays out engineering documentation best practices that produce docs your team actually reads, along with templates and a lightweight review process you can adopt this sprint.
- Background / Why This Matters
- Core Concepts and Architecture
- Implementation Strategy
- Scaling and Operational Considerations
- Common Mistakes / What to Avoid
- Frequently Asked Questions
- Conclusion
Background / Why This Matters
Documentation fails for structural reasons, not moral ones. When you tell a team to "document more," you get more prose and less clarity. The volume goes up; the utility goes down. People write documentation as a compliance exercise — something to satisfy a checkbox in a PR template — rather than as a tool that saves a future colleague an hour of confusion.
The cost is real even if it's hard to measure precisely. Estimates vary, but research on knowledge work consistently suggests that developers spend a meaningful share of their week — often cited as a quarter or more — searching for information or reconstructing context that already existed somewhere. For an engineering manager, that shows up as slower onboarding, bus-factor risk, repeated architectural mistakes, and incident response that depends on whoever happens to be awake.
Good documentation attacks three specific failure modes:
- Knowledge that lives in one head. When only one person understands the payment reconciliation flow, your delivery velocity is hostage to their calendar.
- Decisions that get relitigated. Without a record of why you chose Postgres over DynamoDB, the debate resurfaces every six months with no new information.
- Operational tribal knowledge. The steps to safely restart a service should not require paging the one engineer who remembers them.
Takeaway: Stop framing documentation as "writing more." Frame it as reducing the cost of the next incident, the next hire, and the next architectural argument. That reframing changes what you write and how you measure success.
Core Concepts and Architecture
The single most important idea: documentation is not one thing. Different documents serve different readers under different pressures. Treating them uniformly is why so much documentation is useless. A framework popularized by the Divio "Diátaxis" model splits docs into tutorials, how-to guides, reference, and explanation. For internal engineering work, a slightly more pragmatic taxonomy works better.
The three documents that matter most
| Document type | Primary reader | Read under | Optimize for | Update trigger |
|---|---|---|---|---|
| Architecture doc | New engineer, reviewer | Calm, exploratory | Mental model & boundaries | Major design change |
| Runbook | On-call engineer | Stress, 3am | Speed & unambiguous steps | After every incident |
| Decision record (ADR) | Future team, self | Debate, retrospection | Context & tradeoffs | Never (append new one) |
Notice how the reader's emotional state dictates the format. An architecture doc can afford prose and diagrams. A runbook read at 3am during a P1 incident cannot — it needs numbered steps, exact commands, and no ambiguity about "which cluster."
Architecture Decision Records (ADRs)
ADRs, introduced by Michael Nygard, are the highest-leverage documentation an engineering team can adopt. Each is a short, immutable markdown file capturing one decision. A minimal template:
- Title: ADR-014: Use Postgres for the event store
- Status: Proposed / Accepted / Superseded by ADR-021
- Context: What forces are at play? What constraints exist?
- Decision: What we chose, stated plainly.
- Consequences: What becomes easier, what becomes harder.
The magic of ADRs is that they're append-only. You never edit a superseded decision — you write a new ADR that references it. This gives you a git-like history of your team's thinking, which is invaluable during audits, onboarding, and those recurring "why did we do it this way?" conversations.
Takeaway: Split your documentation by reader and reading context. Adopt three formats — architecture doc, runbook, ADR — and resist the urge to invent more.
Implementation Strategy
The best documentation strategy is the one that lives where engineers already work. Documentation in a separate wiki that requires a context switch will rot. Documentation in the repo, reviewed in the same pull request as the code, stays current.
Docs-as-code
Store documentation as Markdown files alongside the code they describe. This unlocks the entire engineering workflow: version control, pull request review, diffs, and CI checks. Standard tooling that supports this well:
- Markdown in the repo for ADRs (an
/docs/adr/directory) and runbooks. - Diagrams as code using Mermaid (renders natively in GitHub and GitLab) or PlantUML, so diagrams live in version control instead of a stale Lucidchart export.
- MkDocs or Docusaurus to publish the repo docs as a searchable site.
- Backstage (Spotify's open-source developer portal) with its TechDocs plugin if you're at the scale where a central catalog pays off.
A lightweight review process
Heavy documentation processes fail. Nobody schedules a two-hour "doc review meeting." Instead, embed review into work you already do:
- PR template checkbox. Add a line: "☐ Updated relevant docs / ADR / runbook, or N/A because ___." Forcing an explicit N/A is more effective than a passive reminder.
- ADR-before-code for significant decisions. If a change alters an interface, introduces a dependency, or affects more than one team, require an ADR PR first. It's usually 20 minutes of writing that prevents days of rework.
- Post-incident runbook update. Make "update the runbook" a mandatory action item in every incident retro. The person who just debugged it has the freshest context.
- Quarterly doc bankruptcy check. Once a quarter, spend 30 minutes marking clearly stale docs as DEPRECATED at the top rather than pretending they're accurate. A doc labeled "possibly outdated" is far safer than one silently wrong.
Write for the skimmer
Nobody reads documentation linearly. Structure accordingly: a one-sentence summary at the top, descriptive headings, short paragraphs, and code blocks with exact commands. For runbooks, front-load the "if X, do Y" decision tree. Assume the reader is stressed, tired, and scanning.
At Halkwinds, when we take over or modernize a client platform through our Engineering services, the first artifact we produce is not code — it's a set of ADRs and an architecture doc that captures the existing system's reality. It's the fastest way to align a team and surface hidden risk before we touch anything.
Takeaway: Put docs in the repo, review them in PRs, and require an explicit N/A rather than hoping people remember. Small friction in the right place beats big process nobody follows.
Scaling and Operational Considerations
What works for a 10-person team breaks at 100. As you scale, documentation shifts from "a few good docs" to a knowledge management problem with discoverability, ownership, and freshness challenges.
Discoverability
The best-written doc is worthless if nobody can find it. As your corpus grows, invest in search. A developer portal like Backstage gives you a service catalog where every service links to its docs, owner, and runbook. Even simpler: enforce a predictable path convention so engineers can guess where a doc lives (/docs/adr/, /docs/runbooks/) without searching.
Ownership
Docs without owners become orphans. Assign each significant doc an owning team via a CODEOWNERS file so changes route to the right reviewers. Tie documentation ownership to service ownership — the team that runs the service owns its runbook, full stop.
Freshness signals
Trust in documentation collapses the first time someone follows a wrong instruction. Combat this with visible freshness signals:
- A "last reviewed" date at the top of runbooks, checked in the quarterly sweep.
- CI checks that flag broken internal links or references to decommissioned resources.
- An explicit DEPRECATED banner — honesty about staleness is more trustworthy than false confidence.
The role of AI
Estimates vary on how much LLM-assisted tooling accelerates documentation, but it's genuinely useful for the parts engineers hate: generating a first draft from a design discussion, summarizing an incident timeline into a runbook update, or answering "where is X documented?" against your corpus. Treat AI output as a draft that a human owner must verify — an unverified generated runbook is more dangerous than no runbook, because it looks authoritative.
Takeaway: At scale, invest in discoverability, ownership via CODEOWNERS, and honest freshness signals. Use AI to draft, never to publish unverified operational instructions.
Common Mistakes / What to Avoid
- The write-once monolith. A single giant "Architecture" wiki page that tries to document everything. It's never current and nobody reads past the second heading. Split by service and concern.
- Documenting the obvious, omitting the tricky. Autogenerated API reference is fine, but the value is in the non-obvious: why this retry logic exists, what breaks if you change this timeout, which failure modes you've actually seen.
Explore Further