The failure mode of technical documentation is familiar: it gets written during a project, becomes outdated within months, and stops being consulted entirely. Teams work around it, reconstruct knowledge from code and institutional memory, and repeat the cycle with the next project.
Documentation that actually gets used is different in structure, not just quality.
Why most documentation fails
It describes what, not why. A document that says "the order status field accepts values: pending, processing, shipped, delivered, cancelled" is less useful than one that also explains why "on_hold" was removed in v2 and what to use instead. The what is in the code. The why is what developers actually need.
It's written for a fictional reader. Documentation written as if the reader has no context ("Our system processes orders...") is less useful than documentation written for the specific person who will read it — a developer joining the team, a vendor integrating an API, an engineer debugging an incident.
It's not maintained. Documentation that isn't part of the development workflow becomes stale. Stale documentation is worse than no documentation — it actively misleads.
It's too long. Documentation that covers everything comprehensively often gets read by nobody. A two-page decision record explaining why a particular architecture was chosen gets read. A 50-page architecture document does not.
The formats that get used
Architecture Decision Records (ADRs) — short documents (one to two pages) capturing a specific decision: the context, the options considered, the decision made, and the consequences. Written at decision time, not retrospectively. Developers consult them when they're confused about why something works the way it does.
Runbooks — step-by-step operational procedures for specific scenarios: deploying a new service, rolling back a release, responding to a specific alert. Short, specific, tested against real scenarios. Updated when the procedure changes.
API reference documentation — generated from the code (OpenAPI, JSDoc) with human-written context added for non-obvious behavior. Accurate by construction because it comes from the source.
README files with real examples — the document most likely to be read first. Should answer: what does this do, how do I run it locally, how do I run the tests, where do I find X? Code examples over prose descriptions.
The maintenance approach that works
Documentation maintained separately from code drifts. Documentation that lives with the code — in the repository, updated in the same PR as the change it describes — stays accurate.
Make documentation updates a code review requirement. A PR that changes API behavior without updating the API docs doesn't pass review. This is a process constraint, not a motivation constraint, and it's the only approach that reliably keeps documentation current.
The right amount of documentation
More documentation is not better. The right amount is the minimum that allows someone new to the system to become productive and allows the team to make decisions without reconstructing context from first principles.
That minimum is usually less than teams think, and the format matters more than the volume.