Software architecture
Architecture decision record
An architecture decision record (ADR) is a short document that captures one significant design decision, the context that led to it and its consequences.
Teams keep architecture decision records because the reasons behind a design disappear faster than the design does. Six months after a choice of database or messaging pattern, the people who made it have moved on or forgotten, and the next engineer either reopens the argument or works around a decision they do not understand. An ADR gives them one page that says what was decided and why.
Why do ADRs matter?
- They stop repeated arguments. When the reasoning is written down, a new engineer can read it instead of relitigating it.
- They make constraints visible. Many odd-looking parts of a system are the consequence of a sensible decision made under constraints that no longer show.
- They speed up onboarding. Reading the ADR log in order is the fastest way to learn why a system architecture looks the way it does.
- They improve decisions. Writing the context and the alternatives forces the author to have them, which is why ADRs are a natural output of system design.
What are the parts of an ADR?
The diagram at the top of this page shows the structure that Michael Nygard proposed and most teams still use, with one common addition.
- Title. A number and a short name for the decision, such as “ADR 007: Use PostgreSQL for order storage”. Name the decision, not the problem.
- Status. Proposed, accepted, deprecated or superseded, with the date it changed and a link to any record it supersedes.
- Context. The forces at play: the requirements, the constraints, what the team knows and what is already in place. This section explains the decision to someone reading it in two years.
- Decision. What was decided, in one or two sentences in the active voice: “We will store orders in PostgreSQL.”
- Consequences. What gets easier, what gets harder and the work the decision creates. Include the bad ones. A consequences section with no downsides has not been thought through.
- Alternatives considered. Not in the original template, but common: what was rejected and why, so nobody reopens the question with the same options.
What is the ADR lifecycle?
A record starts as proposed when it is written, usually before or during a design review. The review accepts it or rejects it. An accepted record stays accepted until the decision no longer applies, when it becomes deprecated, or until a new decision replaces it, when it becomes superseded and links to the new record. Rejected records are kept too, since the reasoning behind a rejection is as useful as that behind an acceptance.
When should you write an ADR?
Write one for a decision that is hard to reverse, affects more than one team or will be questioned later: a database, a messaging pattern, a framework, a cloud service, an authentication approach or a service boundary. A good test is whether an engineer in a year could reasonably ask “why did we do it this way?”. Also write one when the team takes on deliberate technical debt, so the repayment has a record. Do not write one for decisions a code review can settle, such as naming or library versions.
Where do you store ADRs?
Keep them in the repository of the system they describe, in a folder such as docs/adr/, one Markdown file per record, numbered in order. That puts them under version control, makes them reviewable in the same pull request as the code and keeps them next to the architecture diagrams they refer to, especially when those are kept as diagram as code. Decisions that span several systems, such as those in a solution architecture, go in a shared architecture repository. A wiki works, but records there drift away from the code.
How do you write an ADR?
- Copy the template. Title, status, context, decision, consequences and, if your team uses it, alternatives.
- Write the context first. State the problem, the requirements that matter and the constraints. Keep it to what a reader needs to understand the decision.
- State the decision in one sentence. If it needs more, it may be two decisions.
- List the consequences honestly. Include the new work and the new risks, not just the benefits.
- Record the alternatives. One line each on what was considered and why it lost.
- Propose it and get it reviewed. Open a pull request, discuss it in the design review and set the status to accepted or rejected when the decision is made.
- Link it. Reference the ADR from the design document and the code it affects.
What are common ADR mistakes?
- Recording the decision without the context. “We chose Kafka” tells a future reader nothing about whether the choice still holds.
- Editing accepted records. Changing the decision in place erases the history. Supersede instead.
- Writing them after the fact. An ADR written months later is a guess at the reasoning.
- Too many or too few. Fifty records on library choices bury the ten that matter. None is the common case.
What are some ADR examples?
- ADR 003: Store orders in a document database. Accepted in year one for schema flexibility, superseded by ADR 007 when transactions and reporting became the need.
- ADR 007: Use PostgreSQL for order storage. The record shown above.
- ADR 012: Publish domain events to a message bus. Context: three services polling the orders database. Decision: the order service publishes events, consumers subscribe, a move toward an event-driven architecture pattern. Consequences: eventual consistency, a new piece of infrastructure to run.
- ADR 015: Adopt the C4 model for architecture diagrams. A decision about documentation itself, so every system’s diagrams use the same C4 model levels.
What tools help with ADRs?
- Plain Markdown and a template. A folder in the repository and a template file is the most common setup.
- ADR command-line tools. Small tools that create numbered records from the template and generate an index.
- AI diagramming tools. Tools like Eraser turn the context section of an ADR into an architecture diagram you can keep editing, so a record that says “we will add a message bus between these services” ships with a picture of exactly which services.
For more on this kind of document, see design docs.
Frequently asked questions
-
What does ADR stand for?
ADR stands for architecture decision record. Michael Nygard proposed the format in 2011 as a lightweight log of the decisions that shape a system, one short file per decision, stored with the code. The abbreviation is sometimes read as architectural decision record.
-
What is the difference between an ADR and a design document?
A design document describes a whole design: the problem, the components, the data, the interfaces and the plan. An ADR captures one decision inside that design, with its context and consequences. A design review often produces two or three ADRs, and each stays valid long after the design document is out of date.
-
How long should an ADR be?
One page. Context is usually the longest section at a paragraph or two, the decision is one or two sentences and the consequences are a short list. If a record runs to several pages, it is either a design document or several decisions bundled together.
-
Can you change an ADR after it is accepted?
Fix typos and add links, but do not change the decision. If the team decides differently later, write a new ADR that supersedes the old one and mark the old one superseded with a link to the new record. The history of what was decided and why is the main value of ADRs.