A Snapshot of a Decision at a Moment in Time
An Architectural Decision Record (ADR) is a short, structured document that captures a single, significant architectural decision along with its context and consequences. Think of it like a journal entry for your system's architecture. Each entry records what you decided, why you decided it, and what you expect to happen as a result — written at the moment the decision was made, not months later from faulty memory.
The concept was popularized by Michael Nygard in a 2011 blog post. His insight was that architecture documentation fails when it tries to be comprehensive. A 50-page design document goes stale the moment it's written. Instead, he proposed capturing decisions as a series of small, immutable records — each one focused on exactly one choice.
Key Characteristics of ADRs:
- Immutable History: Once an ADR is "Accepted," you do not go back and edit it. If circumstances change and the decision needs to be reversed, you write a new ADR that supersedes the old one. The original remains as a historical record. This mirrors how Git commits work — you don't rewrite old commits, you make new ones.
- Stored with Code: ADRs live in version control (typically a
doc/adr/ordocs/decisions/folder in your Git repository), right alongside the code and infrastructure they describe. This is critical. Documentation stored in a separate wiki or Confluence space inevitably drifts from reality. Documentation in the repo gets reviewed in pull requests, versioned with releases, and discovered by anyone cloning the project. - Atomic: Each ADR covers exactly one decision. "Use PostgreSQL for user data" is one ADR. "Use Redis for session caching" is a separate ADR. This makes them easy to reference, easy to supersede individually, and easy to search.
- Sequentially Numbered: ADRs are numbered (0001, 0002, 0003...) to create a clear chronological timeline of how the architecture evolved.
What qualifies as an "architectural decision"? Any choice that is hard to reverse, affects multiple components or teams, or constrains future options. Examples: choosing a database, selecting a cloud provider, adopting a service mesh, deciding on an API versioning strategy, choosing between monorepo and polyrepo. Conversely, choosing a variable naming convention or picking a logging library typically does not warrant an ADR.
A common interview question is: "How do you ensure architectural decisions are documented and communicated across teams?" The strong answer is: "We use lightweight ADRs stored in version control, reviewed through pull requests, and numbered sequentially. This creates an auditable decision log that travels with the code." Interviewers are looking for a systematic approach, not "we put it on the wiki" or "we discuss it in Slack." Bonus points if you mention that ADRs are reviewed as part of the pull request that implements the decision — this ties documentation directly to the change, making it impossible to merge code without the rationale.
Key Point: The power of ADRs comes from their constraints, not despite them. By being short (one page), atomic (one decision), immutable (no rewrites), and co-located with code (in Git), they avoid every failure mode of traditional architecture documentation: staleness, discoverability, and scope creep. A 50-page architecture document that nobody reads is worse than no documentation at all — it creates false confidence. A one-page ADR that every engineer reads during onboarding is worth more than any wiki page.