Architecture Decision Records: Capturing Why, Not Just What
Architecture is not only about structures, diagrams, and technologies. It is also about decisions.
Many teams remember what was built, but forget why it was built that way. When context is lost, teams waste time re-debating settled questions, reverse good decisions by accident, or inherit trade-offs they no longer understand.
Architecture Decision Records (ADRs) solve this by preserving the reasoning behind important decisions - not as heavyweight governance, but as lightweight notes that future team members can actually find and read.
What Is an Architecture Decision Record?
An ADR is a small document that captures an important architectural decision, its context, the chosen option, and its consequences. It answers the question: Why did we decide this, and what did we expect to happen?
The widely used format by Michael Nygard keeps ADRs intentionally simple:
- Title - a short name for the decision
- Status - the current state (proposed, accepted, deprecated, superseded)
- Context - the forces at play when the decision was made
- Decision - what was decided
- Consequences - the expected results, both positive and negative
This simplicity is one of the strengths of ADRs. A decision record that takes thirty minutes to write is far more likely to get written than one that requires a committee and a template with forty fields.
Why ADRs Matter
- They preserve architectural memory. Decisions made six months ago fade from collective memory. ADRs keep the reasoning accessible.
- They help future team members understand past reasoning. New developers can read the ADR instead of guessing or asking the one person who might remember.
- They reduce repeated debates. When the same question comes up again, the team can point to the ADR - and either reaffirm or supersede it with new context.
- They make trade-offs explicit. Every decision has consequences. ADRs force teams to name them upfront.
- They support accountability without blame. Decisions are recorded with context, not as finger-pointing exercises.
- They help teams evolve architecture intentionally. When you can see the chain of decisions that shaped a system, you can change direction deliberately rather than accidentally.
- They make it easier to revisit decisions when context changes. The original context is right there in the ADR - you can see whether the forces that drove the decision still apply.
What Makes a Decision Architectural?
Not every decision deserves an ADR. Architectural decisions are those that are hard to reverse, affect many parts of the system, or constrain future options significantly.
Good Candidates for ADRs
- Choosing a modular monolith instead of microservices
- Using asynchronous messaging for a business workflow
- Introducing a transactional outbox
- Choosing PostgreSQL as the primary database
- Defining service boundaries
- Deciding whether to use event sourcing
- Adopting hexagonal architecture for a core domain
Usually Not Worth an ADR
- Small implementation details (naming a variable, choosing a loop structure)
- Temporary coding choices that can be changed in an afternoon
- Local refactorings that do not affect the system boundary
- Decisions that are obvious and easily reversible
A useful heuristic: if the decision would be worth explaining to a new team member joining six months from now, it is probably worth an ADR.
The Nygard ADR Format
Title
A short name for the decision. Prefer an active title that states the decision directly.
- Good: "Use PostgreSQL for the primary database"
- Weak: "Database decision"
- Good: "Use a modular monolith instead of microservices"
- Weak: "Architecture approach"
Status
The current state of the decision. Common statuses:
- Proposed - under discussion, not yet accepted
- Accepted - the team has agreed to follow this decision
- Rejected - the proposal was considered but not adopted
- Deprecated - the decision still applies but is being phased out
- Superseded - replaced by a newer decision (link to the new ADR)
Context
The forces at play. This section should explain the problem, constraints, assumptions, business drivers, technical drivers, and relevant background. Describe the situation that made a decision necessary - not the solution itself.
Good context sections make the decision understandable even to someone who was not in the room. They include enough background that a reader can evaluate whether the original forces still apply.
Decision
The decision that was made. Keep this section direct and unambiguous. Use language like "We will..." or "The system will..."
This is not the place for hedging or explaining alternatives. State the decision clearly.
Consequences
The expected results of the decision - both positive and negative. This is where the trade-offs become visible.
Good consequence sections are honest about what the team is gaining and what it is giving up. They help future readers understand not just what was decided, but what the team knowingly accepted as a cost.
ADR Lifecycle
ADRs are living documents, but they should not be edited to rewrite history. If a decision changes, create a new ADR that supersedes the old one. The original record remains as evidence of how the architecture evolved.
| Status | Meaning | Action |
|---|---|---|
| Proposed | Under discussion | Review and discuss with stakeholders |
| Accepted | Active and in effect | Follow this decision; reference it in code and design |
| Rejected | Considered but not adopted | Keep for reference; explains why this path was not taken |
| Deprecated | Still applies but being phased out | Plan migration away from this decision |
| Superseded | Replaced by a newer ADR | Follow the new ADR; keep this one for historical context |
The key principle: never delete or silently edit an accepted ADR. If the decision needs to change, write a new ADR that explains the new context and supersedes the old one. This preserves the full decision history.
Good ADRs vs Bad ADRs
| Good ADRs | Bad ADRs |
|---|---|
| Explain the problem and constraints | Justify a decision after the fact |
| Name relevant alternatives | Hide trade-offs |
| Make trade-offs explicit | Sound like marketing |
| Are short enough to read | Contain too much implementation detail |
| Are written close to the time of the decision | Are never updated or superseded |
| Are understandable without tribal knowledge | Are used as bureaucracy |
Worked Example
Here is a complete ADR using the Nygard format. This example uses a decision that many teams face early in a project.
ADR-0001: Use a Modular Monolith Instead of Microservices
Status: Accepted
Context:
The team is building a new business application with a complex domain. The product direction is still evolving. The team is small (six developers). Independent deployment of individual capabilities is not yet required. The organization does not yet have mature platform engineering, observability, and operational support for many independently deployed services.
Decision:
We will build the system as a modular monolith with clear internal module boundaries, explicit dependencies, and a shared deployment unit.
Consequences:
Positive:
- Lower operational complexity
- Easier local development
- Simpler transactions
- Faster early delivery
- Clear path to extract services later if needed
Negative:
- Less independent deployability
- Requires discipline to preserve module boundaries
- Poor modularity could still lead to a big ball of mud
- Scaling individual capabilities independently is harder
Copy-Paste ADR Template
Use this template as a starting point. Remove or add sections based on your team's needs.
# ADR-0001: [Short decision title]
## Status
[Proposed | Accepted | Rejected | Deprecated | Superseded]
## Context
Describe the situation that led to this decision.
Include relevant:
- business drivers
- technical constraints
- quality attributes
- assumptions
- risks
- forces or trade-offs
Do not describe the solution here. Describe why a decision is needed.
## Decision
We will [describe the decision clearly].
This means:
- [important implication]
- [important implication]
- [important implication]
## Consequences
### Positive
- [positive consequence]
- [positive consequence]
- [positive consequence]
### Negative
- [negative consequence]
- [negative consequence]
- [negative consequence]
Common Mistakes
- Writing ADRs too late. The best time to write an ADR is when the decision is fresh - during or immediately after the discussion. Retroactive ADRs lose context and often become justifications rather than records.
- Writing ADRs for everything. If every small choice gets an ADR, the important decisions get buried. Focus on decisions that are hard to reverse or affect the system broadly.
- Treating ADRs as approvals instead of records. ADRs record what was decided and why. They are not sign-off documents or change requests.
- Not documenting alternatives. Without alternatives, a reader cannot understand why the chosen option won. The decision looks arbitrary.
- Ignoring consequences. An ADR without consequences is just an announcement. The trade-offs are the most valuable part.
- Letting ADRs become stale. When a decision is superseded, mark the old ADR and link to the new one. Outdated ADRs that still say "Accepted" mislead readers.
- Storing ADRs where developers never look. ADRs in a forgotten wiki are worse than no ADRs at all. Keep them close to the code or in a place the team actually visits.
Where to Store ADRs
The most effective location for ADRs is close to the code - for example, in a /docs/adr folder within the repository. This makes ADRs discoverable during development, version-controlled alongside the code they describe, and reviewable in pull requests.
Teams that use arc42 for architecture documentation have a natural home for ADRs: section 9 (Architecture Decisions). Storing ADRs there connects them to the broader documentation structure while keeping them accessible to the team.
Other options include wikis, architecture portals, or documentation platforms. What matters is discoverability and versioning. If developers cannot find the ADRs during their normal workflow, the records will not be read.
ADRs work especially well when they are part of normal development workflows:
- Pull requests that introduce significant changes
- Architecture reviews and design discussions
- Technical discovery phases
- Onboarding new team members
- Incident follow-ups that reveal architectural gaps
- Major refactorings that change system structure
Practical Advice
- Start small. Write the first ADR for the next meaningful decision your team faces. Do not try to retroactively document every past decision.
- Keep ADRs short. One to two pages is usually enough. If an ADR needs more space, the decision might be too broad - consider splitting it.
- Prefer plain language. Write for a developer joining the team in six months, not for an enterprise architecture review board.
- Review ADRs during architecture discussions. Make ADRs a normal part of how the team discusses and records decisions, not a separate bureaucratic process.
- Link ADRs to code, diagrams, and other decisions. Cross-references make the decision history navigable and connect abstract decisions to concrete implementation.
- Use ADRs to support learning, not to create bureaucracy. If writing an ADR feels like filling out a form, the process needs simplifying.
Preserving Architectural Reasoning
ADRs are not about documenting everything. They are about preserving the reasoning that future architects, developers, and maintainers will otherwise have to rediscover through archaeology, guesswork, or repeated mistakes.
Every system accumulates decisions over time. The question is whether those decisions are visible and understandable - or buried in chat logs, forgotten meetings, and the memories of people who have moved on.
Start with the next decision that matters. Write it down. Keep it short. Make the trade-offs visible. That is all an ADR needs to be.