Stackbook Logo
← Back to Architectural Thinking

Documenting Architecture Decisions

Use lightweight architecture decision records to capture the why behind your system so future teams can change it with confidence.

4 min read

Code shows what a system does. It rarely shows why it was built that way, which alternatives were rejected, or which constraints no longer apply. When the original authors leave, that reasoning vanishes, and teams either treat every odd choice as sacred or tear it down and repeat old mistakes. Architecture decision records, usually called ADRs, are a small, cheap habit that preserves the reasoning alongside the code.

What an ADR Is

An ADR is a short document describing one significant decision: the context, the choice, and its consequences. Michael Nygard popularized the format in 2011, and its strength is how little it asks. One decision per file, a page or less, written when the decision is made. ADRs are immutable history. If a decision changes, you write a new ADR that supersedes the old one rather than rewriting the past.

Write an ADR when a decision is architecturally significant: it affects structure, quality attributes, dependencies, interfaces, or construction techniques, and it would be costly to reverse. Choosing PostgreSQL over DynamoDB qualifies. Choosing a variable name does not.

A Practical Template

# ADR-014: Use PostgreSQL for the orders service

Status:   Accepted (supersedes ADR-006)
Date:     2026-06-01
Deciders: Payments team, platform architect

## Context
Orders need multi-row transactions and ad hoc reporting.
Expected volume is 50 writes per second, growing about 3x per year.
The team has strong relational experience and no DynamoDB experience.

## Decision
We will use managed PostgreSQL with one primary and read replicas.

## Alternatives considered
- DynamoDB: better horizontal scale, but weak ad hoc queries
  and no multi-item joins; reporting would need a second system.
- MongoDB: flexible schema, but we lack the need for it.

## Consequences
+ Strong consistency and familiar tooling.
+ Simple reporting through replicas.
- Vertical scaling limits; sharding would be needed past roughly 5k writes per second.
- We own schema migrations and backups tuning.

Notice the honest negatives. An ADR that lists only benefits is a sales pitch. The consequences section, including what you are giving up and when you would revisit, is what makes a record valuable years later.

The Status Lifecycle

Give each record an explicit status so readers know what is current:

  • Proposed: open for discussion, not yet binding
  • Accepted: in force
  • Deprecated: no longer recommended, but not replaced
  • Superseded: replaced by a named newer ADR

Link superseding records both ways. Over time the sequence of ADRs reads as a narrative of how the architecture evolved, which is far more useful to a new engineer than a polished but static diagram.

Where to Keep Them and How to Make Them Stick

Store ADRs in the repository next to the code, in a directory such as docs/adr, numbered sequentially. Version control gives you history, review, and ownership for free. Wikis drift out of date because nobody reviews changes to them.

Process matters more than tooling:

  • Propose the ADR as a pull request. The review discussion is the decision-making forum, and comments become part of the record.
  • Keep the bar low. A ten-minute ADR written during the decision beats a perfect one never written.
  • Reference ADRs in code reviews and design discussions: "this conflicts with ADR-014, do we want to supersede it?"
  • Add the template to your repository generator so new services start with an ADR directory.
  • Time-box them: writing an ADR should take under an hour, otherwise the decision itself is not yet clear.

Common Failure Modes

  • Documenting after the fact. Retroactive records lose the rejected alternatives, which are the most valuable part.
  • Too many ADRs. If every small choice gets one, nobody reads them. Reserve them for significant decisions.
  • No context. "We chose Kafka" without the constraints that made it right is useless once those constraints change.
  • Never revisiting. Add a revisit trigger, such as a volume threshold or a date, so decisions are tested against reality.
  • Hidden ownership. Name the deciders so questions have somewhere to go.

ADRs complement other documentation. Diagrams, such as the C4 model, show structure. ADRs explain choices. Runbooks cover operations. Each answers a different question.

Key Takeaways

  • Capture the reasoning behind significant decisions, not just the outcome.
  • Keep ADRs short, immutable, one per decision, and stored in the repository.
  • Always list alternatives considered and the honest downsides of the choice.
  • Use statuses and supersession links to tell the evolving story of the architecture.
  • Write them at decision time, through pull requests, and add revisit triggers.