How to Write a Technical Architecture Decision Record (ADR) Your Whole Team Will Actually Use
Est. Read Time: 6 min
Every engineering team makes architectural decisions. Most teams make them, implement them, and promptly forget why. Six months later, a new engineer asks why the system is designed this way, and the person who made the decision either isn’t around or can’t remember. The decision gets second-guessed, re-debated, and either changed for no good reason or preserved for no good reason.
Architecture Decision Records (ADRs) exist to solve this. They’re a lightweight documentation format for capturing significant architectural decisions — what was decided, why it was decided, and what alternatives were considered. This post explains the format, why it matters, and how to make it a practice rather than a policy.
What Is an ADR?
An Architecture Decision Record is a short document — typically one to two pages — that captures one architectural decision. It’s not a design document, a specification, or a technical deep-dive. It’s a record of a decision and the reasoning behind it.
The key word is record — it’s a historical artifact, not a living document. Once an ADR is finalized, it shouldn’t be edited. If the decision changes, a new ADR is created that supersedes the old one. The history of decisions is preserved.
Why ADRs Matter
For onboarding. A new engineer who can read the ADRs for a system understands not just what decisions were made but why. This dramatically accelerates the time it takes to get productive and form useful opinions about the system.
For decision quality. The act of writing down a decision and its alternatives forces the decision-maker to think more clearly. Decisions that look obvious in conversation often reveal complications when written out.
For team alignment. ADRs make architectural decisions visible to the whole team. They create a shared understanding rather than letting important context live only in the heads of the engineers who were in the room.
For avoiding re-litigation. When a decision is documented with its reasoning, future engineers can evaluate whether the original reasoning still applies rather than re-debating the same ground.
For distributed teams. For nearshore and remote teams, ADRs are especially valuable because they can’t rely on hallway conversations to transfer architectural context. A well-maintained ADR log is the closest thing to having been in the room.
The Format That Actually Works
There are several ADR formats in use. The one that works best in practice is a simplified version of Michael Nygard’s original format:
ADR-[number]: [short title of decision]
Date: [YYYY-MM-DD]
Status: [Proposed / Accepted / Deprecated / Superseded by ADR-X]
Context
A paragraph describing the situation, problem, or opportunity that necessitated a decision. This section should explain the forces at play — technical constraints, team capabilities, time pressure, cost considerations, or external requirements.
Decision
A single clear statement of what was decided. Not the reasoning — that comes later. Just what was chosen.
Reasoning
Why was this option chosen over the alternatives? What specific factors made this the best available option given the constraints described in Context?
Alternatives Considered
What other options were evaluated? For each alternative: what was it, what are its advantages, and why was it not chosen?
Consequences
What does this decision mean for the system going forward? What does it make easier? What does it make harder? What constraints does it impose on future decisions?
This format is short enough to actually write and complete enough to actually be useful. An ADR in this format should take thirty to sixty minutes to write.
What Decisions Warrant an ADR
Not every technical decision needs an ADR. The signal for writing one is: would a new engineer or a future version of yourself benefit from knowing why this was done?
ADR-worthy decisions typically include:
- Choice of framework or language for a new service or major component
- Database schema design choices with significant trade-offs
- Authentication and authorization architecture
- API versioning strategy
- Deployment and infrastructure architecture
- Third-party service selection when alternatives were meaningfully evaluated
- Performance trade-offs made for specific constraints (e.g., denormalizing for read performance)
- Security decisions with architectural implications
Decisions that probably don’t need an ADR:
- Library selection for utilities with minimal trade-offs
- Implementation details within a component
- Bug fixes
- Code style decisions (these belong in a style guide)
Making ADRs a Team Practice
The hardest part of ADRs isn’t writing them — it’s making the practice stick.
Location: Store ADRs in the repository they apply to, in a top-level docs/decisions/ directory. ADRs that live in Confluence or Notion get forgotten. ADRs that live next to the code get read.
Numbering: Use sequential numbering (ADR-001, ADR-002, etc.). Simple and unambiguous.
Process: The process that works is: when a significant architectural decision is being made, the proposing engineer drafts an ADR before the decision is finalized. The team reviews and discusses the ADR, and the status changes to “Accepted” when consensus is reached.
Linking: When code implements an architectural decision, reference the relevant ADR in the code or PR description. “This implements the caching strategy described in ADR-017” helps engineers connect the documentation to the implementation.
Supersession: When a decision changes, write a new ADR that states it supersedes ADR-X. Update ADR-X’s status to “Superseded by ADR-Y.” Don’t edit or delete the old ADR.
An Example ADR
ADR-023: Use PostgreSQL rather than MongoDB for the user data store
Date: 2024-09-15
Status: Accepted
Context
We’re designing the user data store for our core platform. User records have a fixed schema that has been stable for two years. We have two engineers with strong PostgreSQL experience and no team members with production MongoDB experience. We’re a three-person team with limited capacity to manage operational complexity.
Decision
Use PostgreSQL as the user data store.
Reasoning
Our user data schema is stable and relational. PostgreSQL’s strong ACID guarantees and well-understood operational characteristics match our requirements. Our team’s existing PostgreSQL expertise means faster development and lower operational risk. Our data access patterns are well-suited to relational query patterns.
Alternatives Considered
MongoDB: Offers flexible schema, which is not a priority given our stable data model. Would require new operational knowledge from the team. No clear advantage for our use case.
MySQL: Strong alternative. Slightly less mature JSON support and fewer advanced features relevant to our future plans. PostgreSQL is preferred given equivalent team familiarity.
Consequences
Future data models that need document storage flexibility will need to evaluate whether PostgreSQL’s JSON support is sufficient before adding a new data store. Migrations will require explicit schema changes, which is a positive forcing function for schema discipline.