Architecture Decision Records: How to Document Decisions That Last
Architecture decision records explained: format, lifecycle, and how ADRs prevent repeated debates and undocumented tech debt in engineering teams.
In this article:
- What an Architecture Decision Record Actually Is
- The ADR Format That Works in Practice
- Where ADRs Fit in Your Architecture Roadmap
- Engineering Standards: Making ADRs a Team Habit
- When to Update or Supersede an ADR
- Conclusion
An architecture decision record (ADR) is a short document that captures a significant architectural decision: what the decision was, why it was made, and what trade-offs were accepted. The concept is simple. The discipline of actually using ADRs consistently is where most engineering teams struggle. This article explains the format, the workflow, and the specific conditions that make ADRs valuable rather than just more documentation overhead.
What an Architecture Decision Record Actually Is
An ADR is not a design document. It is not a spec. It is a log entry for a decision that is consequential enough that future engineers will need to understand why the codebase looks the way it does.
The need for ADRs becomes obvious when you are asked to change something in a system and you find code that looks wrong or outdated. You cannot tell whether it was a deliberate choice, a hack no one got around to fixing, or an outdated pattern from a framework version three years ago. Without an ADR, you spend an hour in git blame and Slack history trying to reconstruct the reasoning. Or worse, you make the change without understanding the constraints and reintroduce a problem that was already solved.
ADRs exist at the intersection of two failure modes that compound technical debt:
Undocumented decisions create tribal knowledge. When the engineer who made the decision leaves, the reasoning leaves with them. New engineers make conflicting decisions, and the architecture drifts inconsistently.
Repeated debates waste time. Teams without ADRs relitigate the same architectural questions every few months because there is no authoritative record of what was decided and why. The database selection debate, the service boundary debate, the authentication approach debate. These conversations repeat because there is no shared memory.
The ADR Format That Works in Practice
The most widely adopted format comes from Michael Nygard’s original proposal and fits on one page. Each section should be concise.
Title. A short phrase describing the decision. ADR-001: Use PostgreSQL for primary persistence.
Status. Proposed, Accepted, Deprecated, or Superseded. Status is critical for lifecycle management.
Context. What forces led to this decision? What constraints existed? What alternatives were considered? This section should read as a neutral description of the problem, not a justification.
Decision. What was decided, stated directly. One or two sentences.
Consequences. What becomes easier as a result of this decision? What becomes harder? What new technical debt is accepted? This section is where intellectual honesty lives. If a decision has real trade-offs, list them plainly.
Optional but useful: Alternatives considered with a brief note on why each was rejected. This prevents the same alternatives from being proposed again without new information.
The entire ADR should be readable in under five minutes. If it is longer, the decision probably needs to be split into multiple ADRs or the consequences section is doing too much work.
Where ADRs Fit in Your Architecture Roadmap
An architecture roadmap describes where the system is going. ADRs document the decisions made along the way. They are complementary, not redundant.
The roadmap tells you the destination. ADRs explain why specific turns were taken. When an engineer joins mid-journey, the roadmap tells them the goal; the ADR history tells them what constraints shaped the path.
For teams doing legacy modernization, ADRs are especially important during the transition period. A strangler fig migration generates dozens of decisions: which module to extract first, how to handle shared data, when to cut over. Without ADRs, each of those decisions exists only in the heads of the people who made them. With ADRs, the migration plan is inspectable and transferable.
The architecture roadmap should reference relevant ADRs. When a roadmap milestone requires a significant technical decision, that decision should have an ADR before implementation begins, not after. ADRs written post-hoc tend to be justifications rather than honest records of trade-offs.
Engineering Standards: Making ADRs a Team Habit
ADRs only work if the team uses them consistently. That requires making the process low-friction enough that engineers actually write them.
Three practices that make ADR adoption stick:
Store ADRs as code. Keep ADRs in the repository, in a /docs/adr/ directory, as markdown files. They are reviewed and merged via pull request, just like code. This gives them the same visibility, versioning, and review process as the code they document.
Define a decision threshold. Not every decision needs an ADR. The threshold question is: will a future engineer need to understand why this was done this way? Useful triggers: choices between competing frameworks or libraries, decisions about service boundaries, changes to data models that cannot be reversed easily, choices that involve accepted risk or known trade-offs.
Make ADR creation part of the pull request process for qualifying changes. When a PR introduces a significant architectural change, the review checklist should include: does this need an ADR? If yes, the ADR is merged alongside the code.
The engineering standards around ADRs should also define who can approve them. For cross-team decisions, the review process should include stakeholders from affected teams. For team-scoped decisions, the team lead or a senior engineer is sufficient. The process scales to the decision’s scope.
One thing to avoid: requiring ADRs for trivial decisions. That creates the same overhead problem that makes all documentation processes fail. The threshold should be clear enough that engineers can self-select without needing approval to write or skip an ADR.
When to Update or Supersede an ADR
ADRs are immutable by convention. You do not edit an accepted ADR. You write a new one that supersedes it. This preserves the historical record and makes it clear that a decision changed, not that it was always what the new ADR says.
When a decision is superseded, update the status of the original to “Superseded by ADR-NNN” and create the new ADR with a reference to the old one. Engineers reading the old ADR will see it is superseded and know to read the replacement.
Deprecation is different from supersession. A deprecated ADR covers a decision that is no longer relevant because the context changed. For example, an ADR about a third-party service that was discontinued. Deprecated ADRs should remain in the repository for historical context.
The software due diligence process often surfaces missing ADRs as a significant risk signal. When a codebase has architectural choices that cannot be explained, it is almost always because the decisions were never documented. Acquiring teams, or teams inheriting a system, face months of reverse-engineering work that a collection of ADRs would have eliminated.
Conclusion
Architecture decision records work because they solve a concrete problem: the gap between the code that exists and the reasoning that produced it. The format is simple. The discipline is harder. Store ADRs as code, define a clear threshold for when they are required, and make them part of the review process for significant changes. Over time, the ADR history becomes the most reliable documentation your system has, because it reflects actual decisions rather than aspirational designs.
Does your codebase have these problems? Let’s talk about your system