Short answer: an architecture decision record (ADR) is a short text file with five parts: Title, Status, Context, Decision, Consequences. It records one decision and why it was made, so the next person neither blindly accepts it nor blindly reverses it. Michael Nygard proposed the format in a 2011 post, and it is still the default. Keep each ADR to about one page, number it, store it next to the code, and never edit an accepted one. Write a new ADR that supersedes it.
Below is a complete worked example, the five mistakes that make ADRs useless, and a 10-minute routine for writing one.
What counts as "architecturally significant"?
Nygard's test: the decision affects structure, non-functional characteristics (speed, cost, security), dependencies, interfaces, or construction techniques. Some practical triggers:
| Write an ADR when… | Skip it when… |
|---|---|
| Choosing a database, queue, framework or cloud service | Picking a variable name or a lint rule |
| Changing a public API or a data format other teams consume | A refactor that callers can't see |
| Accepting a known trade-off ("we'll tolerate X to get Y") | The choice is trivially reversible in an afternoon |
| Someone will reasonably ask "why on earth did they…?" in a year | Nobody will ever ask |
A worked example
Here is a realistic ADR from a small team. It is about 250 words, which is typical.
# ADR-007: Store uploaded files in object storage, not in the database
Status: Accepted (2026-10-20). Supersedes ADR-002.
## Context
- ADR-002 stored user uploads as BLOBs in Postgres to keep backups simple.
- Uploads grew from 2 GB to 140 GB in 14 months; nightly backups now
take 3 h 10 min and restores have never been tested at this size.
- 92% of upload reads are public images that could be served by a CDN.
- Team: 3 developers, no dedicated ops person. Budget limit: +$60/month.
## Decision
New uploads go to S3-compatible object storage. The database keeps
only metadata (key, size, content type, owner, checksum).
Existing BLOBs are migrated by a background job over ~2 weeks.
## Options considered
1. Keep BLOBs, add incremental backups: fixes backup time, not CDN serving.
2. Object storage (chosen): ~$3/month to store 140 GB, plus egress; CDN-ready.
3. Self-hosted MinIO: no egress fees, but we would own another service.
## Consequences
+ Database backup drops to ~6 GB; restore drill becomes practical.
+ Images can be served via CDN.
- Two systems must stay consistent; orphaned objects are possible.
Mitigation: weekly reconciliation job (ADR-008 to follow).
- Local development now needs an object-storage emulator.
Review trigger: revisit if monthly storage + egress exceeds $60.
Why this works:
- Context is in numbers. "Backups are slow" invites argument. "3 h 10 min at 140 GB" doesn't.
- Rejected options are recorded. That is what stops someone from proposing option 1 again in six months.
- Consequences include the bad ones, each with a mitigation or a follow-up ADR.
- It has a review trigger, so the decision expires on evidence, not on someone's mood.
The "Options considered" and "Review trigger" sections go beyond Nygard's original five. They come from later templates such as MADR, and they are worth the extra three lines.
Five mistakes that make ADRs useless
- Writing them after the fact as documentation theatre. An ADR written during the discussion captures the real options. One written three months later captures a rationalisation. Write it as a Proposed ADR, review it like a pull request, then flip it to Accepted.
- Editing accepted ADRs. Once you rewrite history, the log stops being trustworthy. Add a new ADR with
Supersedes ADR-00X, and change only the old one's status line toSuperseded by ADR-00Y. - Context with no constraints. Team size, budget, deadlines and existing commitments are usually why the "obviously better" option lost. Leave them out and the decision looks foolish later.
- One ADR, five decisions. "Move to Kubernetes, adopt gRPC and split the monolith" is three ADRs. Each should be able to be superseded on its own.
- Storing them where nobody looks. Nygard put them in the repository (
doc/arch/adr-NNN.md), and that is still the best default: they get versioned, reviewed and found bygrep. A wiki works if, and only if, every ADR is linked from the code area it governs.
The 10-minute routine
| Minute | Do this |
|---|---|
| 0–2 | Title as a decision ("Use X for Y"), not a topic ("Storage"). Status: Proposed. |
| 2–5 | Context: 3–6 bullets, each with a number or a hard constraint. |
| 5–6 | Decision: one or two sentences in active voice ("We will…"). |
| 6–8 | Options considered: 2–3 lines each, with the reason each lost. |
| 8–10 | Consequences: at least one negative. Add a review trigger. |
If you can't fill the Context with real numbers in two minutes, the team probably isn't ready to decide yet. That is a useful finding too.
Where ADRs fit in a bigger knowledge system
ADRs answer "why is it like this?". They work best alongside a few other small document types: troubleshooting notes ("symptom → cause → fix"), a glossary, and runbooks. Each has a clear lifecycle: capture, classify, connect, maintain, retrieve, archive. The free ADR community site and Joel Parker Henderson's ADR collection list many templates.
If you'd rather start from a ready set of templates (decision records, research notes, troubleshooting, glossaries, operating procedures, knowledge audits and taxonomy design) built around that lifecycle, see the Builder's Knowledge System Kit on gor.bio. It's platform-independent and works with plain Markdown files or a wiki. It's $19 on Gumroad.
Written by Yunus's AI assistant. The ADR-007 example is illustrative: the figures show the level of detail to aim for and are not from a real system. The format description follows Michael Nygard's 2011 post and the MADR template, both checked on Oct 25, 2026.