Skip to content

Documenting Architecture Without It Going Stale

Almost everyone agrees architecture needs documenting, and almost nobody keeps the documentation up to date. A design written at the start of a project is accurate for a while, then drifts away from the system it describes. Stale documentation is arguably worse than none, because readers can’t tell which parts to trust.

The challenge is documenting enough to communicate a design and coordinate the people building it, without creating a body of documents that nobody maintains.

How this plays out depends heavily on the kind of project. On the large enterprise client projects I’ve worked on, a formal up-front design was often required: Word documents following a “solution blueprint” format, kept in SharePoint, versioned by filename, and approved by an architecture board before work could start. That’s good for the initial documentation, and it’s genuinely more useful on integration projects, where several teams have to agree the interfaces between their systems. But blueprints tend to become very heavy, and they start going out of date soon after sign-off.

Other formats fail in their own ways. Wikis are easy to write, but pages are rarely updated, and it’s hard to know what’s still current. Diagramming tools drift the same way; I used Visio heavily in the past, mostly on waterfall-style or integration projects describing the system context.

Agile projects write less up front, but the problem doesn’t go away. On a long-running codebase, whatever documentation does exist drifts just the same.

  • Up-front agreement vs. living documentation: architecture boards and cross-team integration need a documented design to agree on, and that’s a legitimate need. But the more detailed the up-front design, the faster it goes stale, and when the document becomes a gate, the process itself becomes the bottleneck.

  • Completeness vs. maintainability: every document written is a document to maintain. Like tests, documentation has a cost, and more of it isn’t automatically better.

  • Thinking vs. keeping: whiteboard-style tools are fast and good for collaborating and exploring a design. Diagrams as code, such as Mermaid, can be versioned and reviewed alongside the code, which makes them far more likely to stay current, but they’re slower to think with.

Document less. Only document what earns its keep. The less there is, the more chance it stays current.

Leave the detail to the code. Component- and code-level detail isn’t worth maintaining separately; the code is the model. Where a rule matters, such as a dependency direction, I’d rather the build enforce it than a document describe it.

Keep a few things current. The ones worth maintaining are:

  • C4 context and container views (see Communicating), which change slowly.
  • Onboarding guides and runbooks: how to run, deploy and support the system.
  • For lower-level detail, a few key workflows as sequence or activity diagrams, where the flow isn’t obvious from the code.

Make some documents point in time by design. Architecture Decision Records are never rewritten. A decision that changes gets a new ADR that supersedes the old one, so the record can’t go stale: it always says what was decided, and why, at the time.

Use both kinds of diagram, for different jobs. A whiteboard tool is for exploring a design and working on it together. Diagrams as code are for the diagrams that are kept.

Keep documentation close to the code. Markdown and diagrams as code in the repository, updated in the same pull request as the change they describe, is the approach I’m moving to. Long-running projects that predate it can adopt it incrementally, starting with the documents that change most.

  • Solution blueprints that grew very heavy, and were out of date soon after they were approved.
  • Wiki pages written at the start of a project and never updated, so nobody knows what still holds.
  • Diagrams that drifted away from the system once the initial design work was done.
  • Decision documents that became a gate every decision had to pass through.