Architecture Decision Records
An Architecture Decision Record (ADR) is a lightweight document — typically a single Markdown file checked into the codebase — that captures the context, decision, and consequences of one significant architectural choice. The format was popularized by Michael Nygard in a 2011 blog post titled Documenting Architecture Decisions; it was promoted from “interesting idea” to “industry standard practice” when ThoughtWorks’s Technology Radar placed Lightweight Architecture Decision Records into the Adopt ring in 2018, signaling that the practice had passed the threshold of broad applicability. ADRs are intentionally minimal — most are 1–2 pages of Markdown — and intentionally immutable once accepted. When a decision is reversed, you don’t edit the original ADR; you write a new one that supersedes it, and the original record is preserved with a status of “Superseded by ADR-NNN.” The discipline produces an audit trail of architectural reasoning over time, which is the artifact that makes long-lived codebases comprehensible. Without ADRs, architectural decisions live in the heads of the engineers who made them; when those engineers leave, the decisions become tribal knowledge, and the next generation of engineers either re-litigates the same decisions or, more often, accepts the existing structure without understanding why it was chosen and is unable to evolve it intelligently. ADRs convert architecture from oral tradition to written record. This note covers the origin, the canonical template (with a full template appendix), the supersession pattern, the relationship to formal architecture documentation (UML, IEEE 42010), and the operational practice of integrating ADRs into a development workflow.
1. Why ADRs Exist — The Tribal-Knowledge Problem
Software architecture decisions have a peculiar life cycle. They are made in conversations — design meetings, Slack threads, lunchtime arguments, whiteboard sessions — and the decision crystallizes when someone writes the first line of code that embodies it. The conversation is rich: it considers alternatives, weighs tradeoffs, references prior experiences, anticipates failure modes. The code that results is sparse: it shows what was chosen, but not why, not what alternatives were rejected, not what would change the decision.
A few months later, a different engineer reads the code. They see the structure but not the reasoning. They wonder: “Why is this service split into two pieces? Why doesn’t it use database X like everything else? Why is there this awkward async hop in the middle?” If the original engineers are still around, they answer in conversation, and the rationale lives another day. If they have left the company, or moved teams, or simply forgotten, the rationale is lost — and the new engineer is left choosing between three failure modes:
- Cargo-cult preservation. Don’t touch the structure; assume there must be a reason. Result: the system calcifies. Sound reasoning that has expired (e.g., “we used DB X because Y was unstable in 2019; Y is fine now”) goes uncorrected, and the workaround becomes permanent.
- Reckless rewriting. Tear out the structure as “obvious legacy junk.” Result: rediscover the original problem the structure was solving — usually as a production incident — and reintroduce something equivalent.
- Re-litigation. Spend a quarter rediscovering the alternatives, weighing the tradeoffs, and deciding again. Result: the same decision is made (the original engineers were not wrong), but at the cost of a quarter of engineering time.
All three are expensive. The fourth option — having the original reasoning in writing, version-controlled, alongside the code — is what ADRs provide. The new engineer reads ADR-0042 (“Why we chose Postgres for the user service”), sees the alternatives considered, the tradeoffs evaluated, and the prevailing context. If the context still applies, they leave the structure; if the context has changed (Y is fine now), they write ADR-0089 explicitly superseding ADR-0042, and the chain of reasoning is preserved.
The deeper observation: architectural reasoning is a different artifact from architectural structure. Code captures structure. Architecture diagrams capture structure. Tests capture behavior. None of them capture reasoning. ADRs are the only common artifact that captures why a structure exists. That is why they have become indispensable in long-lived codebases.
2. Origin — Nygard 2011 and Earlier Influences
The term and format were popularized by Michael Nygard in his November 2011 blog post Documenting Architecture Decisions on cognitect.com. Nygard was already a recognized voice in software architecture — his 2007 book Release It! Design and Deploy Production-Ready Software had introduced the Circuit Breaker Pattern and the stability patterns vocabulary that the operations community had widely adopted. The 2011 ADR post was a short, practical piece (~600 words) that proposed a simple template (the four-section template covered in §4 below) and suggested ADRs be checked into the source repository alongside the code.
Nygard’s framing was deliberately minimalist. The post does not propose a workflow, a tool, or a meta-process. It proposes a file — a small Markdown file with four headings — and a convention: when you make an architectural decision, write one. The simplicity is the point: ADRs that take 30 minutes to write actually get written; ADRs that require a 5-page template, a review committee, and a UML diagram do not.
Two earlier influences are worth noting:
- Tyree & Akerman 2005 — a paper in IEEE Software titled Architecture decisions: Demystifying architecture proposed a more elaborate template with 13 sections (Issue, Decision, Status, Group, Assumptions, Constraints, Positions, Argument, Implications, Related decisions, Related requirements, Related artifacts, Related principles, Notes). This was conceptually correct — capture the reasoning — but operationally heavy. Few teams ever filled out all 13 sections. Tyree & Akerman’s paper is the intellectual precursor of ADRs; Nygard’s contribution was to strip the format down to the minimum that would actually be used.
- Architecture haiku / 1-page architecture description — there had been a long-running thread in the architecture community about “lightweight” architecture documentation as a counter to the heavyweight practices that dominated 1990s software architecture (formal Software Architecture Documents per IEEE 1471, later 42010; Rational Unified Process artifacts; UML-everything). Nygard’s ADRs landed in this thread and crystallized it.
ThoughtWorks promoted ADRs to the Adopt ring of its Technology Radar in May 2018 (technique entry: “Lightweight Architecture Decision Records”), which is the moment ADRs broke into broad mainstream adoption. The Tech Radar’s “Adopt” ring means we feel strongly that the industry should be adopting these items; subsequent radars in 2019 and 2020 reaffirmed the adoption. By 2020 most major Spring / Java / .NET enterprise codebases ship with an architecture/decisions/ or docs/adr/ folder.
The variant called MADR (Markdown Any Decision Records, sometimes Markdown Architecture Decision Records) — maintained at https://adr.github.io/madr/ — is a slightly expanded template that has gained traction in the 2020s; it adds optional sections for Considered Options and Pros and Cons. MADR is the most widely adopted ADR template in 2026.
3. The Canonical Template
Nygard’s original template has four sections. Most variations expand to five or six. Here is the canonical structure with each section’s purpose explained.
3.1 Title
A short noun phrase describing the decision, prefixed with a sequential number: ADR-0042: Use Postgres for the User Service Database. The number is global to the project (or to the directory of ADRs; 0042 is the 42nd decision recorded). The numbering is sequential, never re-used, and once assigned never changes — even if the ADR is later superseded.
3.2 Status
One of: Proposed, Accepted, Deprecated, Superseded by ADR-NNN. Some variants add Rejected (decision was considered and not adopted), Pending (under review), or Replaced (a softer form of “Superseded”). The status field is the single piece of the ADR that can be edited after the fact — when an ADR is superseded, you update its status to point at the superseding ADR. The body (Context, Decision, Consequences) is never edited.
3.3 Context
The forces in play at the time of the decision: the constraints, the requirements, the existing structure, the relevant prior decisions. Nygard’s original framing: “The issue motivating this decision, and any context that influences or constrains the decision.” The context is a snapshot of the world as it was when the decision was made. Six months later the context may have changed; that is fine, and that is why supersession exists. The original context is preserved untouched as historical record.
The Context section is the most often under-written part of an ADR. New engineers writing their first ADRs sometimes write a one-line context and proceed straight to the decision; the result is an ADR that reads as “we decided X” without explaining what made X the right answer at the time. A good Context section explicitly names:
- The problem being solved.
- The constraints — technical, organizational, regulatory, financial.
- The prior decisions that this decision must be consistent with.
- The alternatives that were considered (sometimes split into a separate “Options” section in MADR-style templates).
- The non-functional requirements (latency, availability, throughput, security, cost) that drive the choice.
A Context section that names all of these is enough for a future reader to evaluate whether the same decision would still apply.
3.4 Decision
The actual decision, stated declaratively in the present tense. “We use Postgres 14 with logical replication for the User Service database. The schema lives in the user-service/db/migrations/ directory. We do not use the JSONB type for primary entity storage; structured columns are used instead, with JSONB reserved for sparse extension fields.”
The Decision section is short — usually 1–3 paragraphs. It says what was chosen, with enough specificity that a reader can map the decision to the code. It should not re-state the Context; it should not enumerate the alternatives; it should not justify itself (justification belongs in Context and Consequences). It is just the what.
3.5 Consequences
The implications — both positive and negative — of having made this decision. Nygard’s framing: “The resulting context, after applying the decision. All consequences should be listed here, not just the ‘positive’ ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.”
Consequences are where the ADR becomes most useful for future readers. They cover:
- What this decision enables. (Positive: “We can use Postgres’s robust transaction semantics for cross-table consistency.”)
- What this decision costs. (Negative: “We require operational expertise in Postgres tuning, replication, and backup; we are paying for an RDS Postgres instance per environment.”)
- What this decision precludes. (Negative: “We cannot use the schemaless flexibility of MongoDB for entity definitions; new fields require schema migrations.”)
- What follow-up decisions must be made. (Neutral: “We must decide on a connection-pooling strategy, a migration framework, and a backup strategy.”)
- What conditions would trigger reconsidering this decision. (Forward-looking: “If the service’s data scale exceeds 5 TB, or if write QPS exceeds 50k, we should re-evaluate against a horizontally-scalable alternative.”)
The forward-looking consequences are the most valuable for long-term maintenance. They explicitly say what to watch for that would invalidate the original reasoning. A new engineer encountering 5 TB of data in the user service can find ADR-0042 and see that this scale triggers reconsideration — converting an implicit “this is getting weird” into an explicit “we have crossed a known re-evaluation threshold.”
3.6 (Optional) Alternatives Considered
In MADR-style templates, the alternatives are split out from Context into their own section. Each alternative is named and briefly evaluated for its pros and cons. The selected option is identified at the end of the section, leading into the Decision section.
This explicit alternatives-listing is valuable for two reasons: it forces the decision-makers to name the alternatives (preventing the failure mode of choosing a default without considering options), and it gives future readers a clear “we considered X and rejected it because Y” reference. Without this, future readers may waste time reconsidering an alternative that was already evaluated and rejected.
4. Worked Example — A Realistic ADR
To anchor the abstract template in a concrete artifact, here is a complete, realistic ADR for a hypothetical project decision.
# ADR-0007: Use Apache Kafka as the Event Backbone for Cross-Service Communication
## Status
Accepted (2024-03-12). Supersedes ADR-0003 (Use RabbitMQ for inter-service messaging).
## Context
We are migrating from a monolithic e-commerce backend to a microservices architecture
(see ADR-0001 for the architectural-style decision). The migration's first phase is
the Order, Payment, Inventory, and Shipping services. Each service emits events that
the others must observe (e.g., OrderPlaced, PaymentCaptured, InventoryReserved,
ShipmentScheduled). We need a transport for these events.
The non-functional requirements:
- **Throughput**: peak 50k events/second across all services. Current monolith peak
is 12k events/second; we project 4× growth over 18 months.
- **Durability**: events must survive single-broker failure; we cannot lose committed
events.
- **Replay**: in case of a service bug, we need to replay events from a point in time
to rebuild downstream state.
- **Ordering**: per-entity ordering is required (events for OrderID=123 must be
processed in order); cross-entity ordering is not.
- **Retention**: 30-day default retention; some event types require 1-year retention
for audit/compliance.
- **Multi-consumer**: the same event must be consumed by multiple services; each
consumer maintains its own offset.
- **Operability**: we have a 5-person platform team; the chosen solution must fit
their bandwidth.
We currently use RabbitMQ (per ADR-0003) for inter-service messaging in the monolith
era. RabbitMQ has worked for synchronous-style RPC over message queues but does not
fit the new requirements (no native replay; per-queue throughput hits a wall around
20k msg/s; durable retention is awkward).
## Considered Options
1. **Apache Kafka** — distributed, partitioned, append-only log; designed for
high-throughput event streaming.
2. **AWS Kinesis** — managed log-streaming; less operational burden.
3. **Apache Pulsar** — unified messaging-and-streaming; promising but smaller community.
4. **NATS JetStream** — lightweight; less proven at our target scale.
5. **Continue with RabbitMQ + adopt Streams** (RabbitMQ 3.9+ has streams) —
incremental upgrade.
## Decision
We adopt **Apache Kafka 3.5+** (KRaft mode, no ZooKeeper) as the event backbone.
Specific choices within Kafka:
- 3-broker cluster per region, replication factor 3, min in-sync replicas 2.
- Partition count: 32 per topic by default; 128 for the high-volume Order topic.
- Schema registry: Confluent Schema Registry with Avro schemas for all events.
- Consumer offsets: committed manually after successful processing (at-least-once
delivery).
- Retention: 30 days for most topics; 365 days for audit-tagged topics.
We continue using RabbitMQ for *intra-service* request/reply RPC for the duration of
this migration; RabbitMQ will be deprecated in a future ADR once cross-service
communication has fully moved to Kafka.
## Consequences
### Positive
- We meet the throughput, durability, and replay requirements with significant
headroom.
- The append-only log model aligns with our move toward event-sourced microservices
(see ADR-0005).
- Kafka has a large ecosystem (Kafka Streams, Kafka Connect, Schema Registry) that
enables incremental capability adoption.
### Negative
- Operational complexity is significant. Our 5-person platform team will need
Kafka-specific training. We are budgeting 2 engineer-quarters for the initial
cluster build-out and operations playbook.
- Cost: the 3-broker cluster (3× r5.2xlarge in 3 AZs per region, plus EBS storage)
is approximately $9k/month/region versus $2k/month for our current RabbitMQ
cluster.
- We are committing to Avro schemas as a default. Switching to Protobuf or JSON Schema
later would be a multi-quarter migration.
- The migration off RabbitMQ for cross-service communication will take ~2 quarters.
### Forward-Looking
- We will revisit this ADR if sustained throughput exceeds 200k events/second
(Kafka can scale further but partition counts will require attention) or if our
platform-team operational bandwidth becomes inadequate.
- We will revisit if a managed Kafka offering (MSK, Confluent Cloud, Aiven) becomes
significantly cheaper than self-hosted; our current cost calculation assumes
self-hosted on EC2.
- We will write follow-up ADRs for: schema-evolution policy (ADR-0008), exactly-once
semantics (ADR-0009), cross-region replication strategy (ADR-0010).
## References
- ADR-0001: Adopt Microservices Architecture
- ADR-0003: Use RabbitMQ for Inter-Service Messaging (now superseded by this ADR)
- ADR-0005: Adopt Event Sourcing for the Order Service
- Kafka documentation: https://kafka.apache.org/documentation/
- Confluent's "Designing Event-Driven Systems" by Ben Stopford (free O'Reilly book)
This example shows several common features:
- The Status section identifies what this ADR supersedes, tying the chain of decisions together.
- The Context section names the prior decision (ADR-0003), the relevant requirements, and the constraints. It is dense but each fact is necessary.
- The Decision section is specific enough to be actionable — partition counts, replication factor, schema registry — but not so specific that it becomes operations documentation.
- The Consequences section is honest about negatives — operational complexity, cost, migration effort. An ADR that lists only positives is suspect; every architectural decision has tradeoffs.
- The Forward-Looking subsection makes the re-evaluation triggers explicit, which is what makes this ADR durable as a future-reader artifact.
5. The Supersession Pattern
The single most important operational discipline in ADRs is never edit a past ADR. When a decision is reversed or evolved:
- Find the original ADR (say, ADR-0003).
- Write a new ADR (say, ADR-0007) that explicitly supersedes it. The new ADR’s Context section should reference the old ADR and explain what changed.
- Update the Status line of ADR-0003 to read
Superseded by ADR-0007. This is the only edit allowed to a past ADR — a single-line status update with a forward pointer. - Leave the body of ADR-0003 (Context, Decision, Consequences) untouched. Future readers must be able to see the original reasoning as it was.
The supersession chain creates an audit trail. ADR-0003 says “we use RabbitMQ for inter-service messaging” and is superseded by ADR-0007 which says “we use Kafka.” A future engineer can follow the chain and see both decisions, with their respective contexts. They learn why RabbitMQ was originally chosen (perhaps the throughput requirements at the time were different) and why it was replaced (the new requirements). This is far more useful than seeing only the current state (“we use Kafka”) — the new engineer can reason about whether the current context still favors Kafka or whether circumstances have changed enough to warrant another supersession.
Why not just edit ADR-0003 in place to say “we use Kafka now”? Because:
- The historical record is destroyed. Future readers cannot see the prior reasoning, so they cannot evaluate whether it was sound.
- Decisions appear ahistorical. “We use Kafka” without context looks arbitrary; “we used RabbitMQ until 2024 because of X, then moved to Kafka because of Y” tells a story that aids reasoning.
- The audit trail is broken. Many engineering organizations are subject to compliance regimes that require traceability of architectural decisions; the supersession-chain pattern preserves that traceability.
The discipline takes practice. Engineers’ instinct is to update existing documents; the ADR discipline runs counter to that instinct. Teams that adopt ADRs typically need 6–12 months and 20+ ADRs before the supersession reflex becomes natural.
6. Why “Lightweight” Matters
The lightweight nature of ADRs is not incidental; it is the load-bearing design choice of the format. Heavyweight architecture documentation has a long history in software engineering — IEEE 1471 (1998), updated to ISO/IEC/IEEE 42010 (2011), formalizes a Software Architecture Description (SAD) with views, viewpoints, stakeholders, concerns, models, model kinds, correspondences, and a half-dozen other meta-concepts. The Rational Unified Process prescribes a Software Architecture Document with a similar structure. These artifacts are extensively documented in the literature and are almost never maintained in practice.
The failure mode is the same in every team that has tried it: the heavyweight document is written at project kickoff, distributed for review, edited based on review, signed off, and then not updated. Six months later it bears no relationship to the actual system. A year later it is misleading — describing structures that have been replaced. Engineers learn to ignore it, and the heavyweight document fails its purpose.
The mechanism: documentation that is expensive to update will not be updated. The architecture moves; the document stays still; the gap between them grows; the document loses credibility; engineers stop reading it; the document is dead. This pattern is so reliable that veteran architects refer to “the wallpaper SAD” — a Software Architecture Document that exists, has been formally signed off, and is on a Confluence wiki page that nobody opens.
ADRs sidestep this failure by being:
- Small. A single ADR is 1–2 pages; writing one takes 30 minutes if the decision is fresh in the writer’s mind.
- Plain text. Markdown, in the codebase, in version control. Editable by any engineer; reviewable in a pull request.
- Immutable. Once accepted, never edited. So there is no “keep it up to date” maintenance burden — the historical record is preserved by not touching it.
- Per-decision. The cost of writing an ADR is paid only when a decision is made; there is no “let’s document the architecture” project that has to compete with feature delivery.
- Co-located with code. The ADRs live in the repo, alongside the code they describe. Engineers see them when they browse the repo. Pull requests can update ADRs alongside code changes that supersede prior decisions.
The cost-benefit ratio is what makes ADRs sustainable. A team that maintains a “wallpaper SAD” is paying maintenance cost continuously; a team that maintains ADRs is paying cost only when decisions happen. The latter scales; the former doesn’t.
Note: ADRs are not a substitute for high-level architecture diagrams or formal system documentation. A team that needs a system overview should still produce one (using C4 model diagrams, or a README, or whatever fits). ADRs are a complement to those artifacts: the diagrams and overviews show what is; the ADRs show why. Both are needed; ADRs are the historically-undermaintained half.
7. Comparison with Formal Architecture Documents (UML, IEEE 42010, C4)
To position ADRs in the broader landscape of architecture documentation:
7.1 IEEE 42010 / ISO 42010
The international standard for “architecture description” defines a heavyweight conceptual model: an architecture description has views, each addressing one or more concerns of stakeholders, conformant to a viewpoint (a template/method for the view), and the views are kept consistent via correspondences. This is sound abstract framework but operationally enormous. Few teams produce a complete IEEE 42010 description; those that do typically do so for regulated industries (defense, aerospace, medical devices) where the standard is mandated. ADRs are not a replacement for IEEE 42010; they are a much smaller artifact.
7.2 UML Diagrams
UML (Unified Modeling Language) provides 14 diagram types covering structure (class diagrams, component diagrams, deployment diagrams) and behavior (sequence diagrams, state machines, activity diagrams). In the 2000s, “architecture documentation” often meant “UML.” The practice has declined since 2010 because UML diagrams are expensive to maintain (a single architectural change can require updating five diagrams), drift quickly from the code, and are over-detailed for most architectural questions. Modern practice retains UML for specific cases — a sequence diagram for a complex protocol; a state machine for a workflow — but does not use UML for the broad “what is this system?” documentation. ADRs cover a different scope: why decisions were made, not what the system looks like.
7.3 C4 Model
Simon Brown’s C4 Model (Context, Containers, Components, Code) is a more modern, lightweight diagramming approach. C4 prescribes four levels of zoom — system context, container, component, code — and resists going beyond them. C4 diagrams are simpler than UML and often suffice for “what is this system?” documentation. ADRs and C4 are complementary: C4 diagrams show structure; ADRs explain why the structure is what it is.
7.4 README and Wiki Pages
The most common architecture documentation in the wild is a README.md plus a few wiki pages. These are useful for orientation but typically do not capture decision history. A README plus a docs/adr/ folder of ADRs is a robust combination: orientation in the README, decisions in the ADRs.
7.5 The Right Combination
A mature codebase typically has:
- A README for project orientation and quick-start.
- A C4 system context and container diagrams for “what is this system?” at a glance.
- A
docs/adr/folder containing all the architecture decisions with their reasoning. - Inline code comments for low-level implementation choices.
- Test cases that document behavior (the test names act as behavior documentation).
ADRs sit in the middle of this stack — too detailed for the README, too high-level for code comments, fundamentally about reasoning in a way the diagrams are not.
8. Tooling — adr-tools, MADR, GitHub Integrations
A modest tooling ecosystem has grown around ADRs:
- adr-tools (Nat Pryce, https://github.com/npryce/adr-tools) — a set of Bash scripts that scaffold new ADRs, list them, and update statuses. Commands like
adr new "Use Postgres for User Service"andadr supersede ADR-0003 ADR-0007automate the boilerplate. This is the original tooling; it remains widely used in 2026. - MADR (https://adr.github.io/madr/) — Markdown Any Decision Records. A community-maintained template that adds optional sections and prescribes a more rigorous numbering. The MADR repo includes scripts and templates.
- adr-log — auto-generates a table-of-contents file (often
docs/adr/README.md) listing all ADRs with their statuses. Useful for navigation in a large directory. - adr-viewer — generates a static HTML site from a folder of ADRs. Useful for browser-based browsing without checking out the repo.
- GitHub integrations — many teams use issue templates and pull-request templates to scaffold ADR proposals. An ADR proposal is filed as a PR adding a new file to
docs/adr/; the PR review is the architectural review; merging is the “Accepted” status.
The tooling is deliberately minimal. The point of ADRs is the discipline, not the tools.
9. Workflow — Integrating ADRs into Development
A mature ADR practice integrates with the development workflow at several points:
9.1 Proposal
A team member proposes a decision by filing a pull request that adds a new file docs/adr/ADR-0042-use-postgres.md with status Proposed. The PR description explains the proposal; the PR review is the architectural review. Reviewers comment on the Context, the Alternatives, the Decision, and the Consequences. The author iterates.
9.2 Acceptance
When the team agrees, the ADR is merged with status Accepted. The Accepted status is the canonical “this is what we are doing” signal. The merge usually happens alongside (or just before) the code change that implements the decision.
9.3 Implementation
The code that embodies the decision is shipped in subsequent PRs. Comments in code can reference the ADR (e.g., // Per ADR-0042: see docs/adr/ADR-0042.md). The ADR is the why; the code is the what.
9.4 Supersession
When the decision is reversed or evolved, a new ADR is filed (per §5). The old ADR’s status is updated; the new ADR’s Context references the old. The supersession is itself a PR, reviewed by the team.
9.5 Rejection
Some decisions are proposed and rejected. The ADR can be left in the repo with status Rejected, or it can be closed without merging. The former preserves the consideration as a record (useful for “we considered this and decided against it” lookups). The latter keeps the repo cleaner. Different teams choose differently.
9.6 Review
Periodic ADR review (quarterly or yearly) is a mature practice. The team reviews accepted ADRs and asks “do the consequences still apply? Has the context changed? Should anything be superseded?” This is the forward-looking part of the ADR Consequences section actually being checked.
10. The Connection to Conway’s Law
ADRs are an artifact of an organization’s current state of architectural knowledge. They are written by the people who own the relevant parts of the system, in the language and frame the team uses. By Conway’s Law, the ADRs that get written reflect the team boundaries — there will be no ADR documenting the seam between two teams unless one team writes it (and the other team accepts it).
This produces a useful diagnostic: which decisions in your system have no ADR? The answer is usually one of:
- Decisions made before ADR adoption. These are tribal knowledge by default; ADR-ifying them retroactively is sometimes worthwhile.
- Decisions that span team boundaries with no clear owner. Conway’s Law strikes: nobody owns the decision, so nobody writes the ADR. The seam is fragile because it has no captured reasoning.
- Decisions that were made implicitly. “We just kind of started using X” — the decision happened by accretion, and there was never a single moment to write it up. Implicit decisions are the most dangerous because they are not visible as decisions and so are not consciously revisited.
A mature ADR practice catches all three: explicit retroactive ADRs for legacy decisions; cross-team ADRs signed off by both sides for boundary-spanning decisions; explicit we are choosing X moments for what would otherwise be implicit accretion.
The deeper point: ADRs are an organizational artifact, and their adoption (or absence) reflects the organization’s relationship with architectural discipline. A team that does not write ADRs is not necessarily disorganized — they may be making good decisions in conversation. But the decisions are not durable across team membership changes; they are only as good as the institutional memory.
11. Interview Discussion Points
ADRs come up in interviews in several characteristic ways:
- “How do you document architecture decisions at $current_employer?” A strong answer names ADRs explicitly, describes the format used (Nygard-style, MADR), gives an example, and discusses the supersession discipline. A weak answer is “we have a Confluence wiki” (the wallpaper-SAD failure mode) or “we don’t really document, the decisions are in the code” (tribal knowledge).
- “How would you onboard a new engineer to a complex codebase?” ADRs are part of the answer — point them at the
docs/adr/folder so they can read the architectural reasoning chronologically. This signals you understand that reasoning is the artifact a new engineer needs, not just structure. - “How do you make sure the team’s decisions are aligned?” ADRs again — the proposal-and-review process for ADRs is itself the alignment mechanism. A proposed ADR is a forcing function for the team to discuss the decision openly.
- “What’s the difference between architecture and design?” (See Architecture Styles vs Patterns vs Frameworks §6.) ADRs are mostly for architectural decisions — the ones hard to change later. Design decisions can be in code comments. The boundary is fuzzy but the rule is “if reversing the decision would take more than a sprint, write an ADR.”
- “Have you been in a codebase that calcified because nobody understood the original decisions?” Most experienced engineers have. ADRs are the structural answer to this failure mode.
- “What does ‘lightweight architecture documentation’ mean to you?” ADRs (or MADR, or some equivalent) is a strong answer. Pair with C4 diagrams or similar for structural views.
- “Show me an ADR you’ve written.” This question filters for actual practice. Bring 1–2 examples (sanitized) you can speak to.
The signal value: ADR fluency suggests the candidate has worked at a place that thinks about architecture explicitly. ADR-illiteracy is not disqualifying but suggests less mature engineering culture in their background.
12. Pitfalls
12.1 ADRs as Bureaucracy
The risk: a team adopts ADRs, then makes the ADR process heavy. ADRs require multi-person sign-off; ADRs require a 5-page template; ADRs require a 2-week review cycle. The result: nobody writes ADRs because the cost is too high; decisions go undocumented again; the team is back where it started, but with a wiki page about the process. The fix: keep ADRs lightweight in practice. A 30-minute write, a one-day async review, a merge.
12.2 Never Updating Status
The classic failure: a team writes 50 ADRs over two years, supersedes some of them in conversation, but never updates the Status lines. New engineers read the docs/adr/ folder and see 50 ADRs all marked Accepted, several of which contradict each other. The fix: when superseding, update the old ADR’s status as part of the same PR that creates the new ADR. Make this a checklist item in the PR template.
12.3 ADRs That Document Trivia
Some teams overcorrect after adopting ADRs and start writing ADRs for every decision, including trivia (“ADR-0042: We named the function parseUser rather than parseUserData”). The result: the ADR folder fills with noise, signal-to-noise ratio collapses, the practice is abandoned. ADRs are for load-bearing decisions — choices that meaningfully constrain the system or its evolution. Trivia goes in code review or PR descriptions.
12.4 ADRs Without Code Linkage
An ADR that does not point to the code it describes is half-useful. A reader reading ADR-0042 should be able to navigate to the code that implements the decision. Conversely, the code should reference the ADR (in comments, in the README, in CODEOWNERS). Without bidirectional linkage, the ADR and the code drift apart and the reader cannot tell which is currently in force.
12.5 Treating Acceptance as Permanence
An accepted ADR is the current state of reasoning, not the eternal truth. Teams that treat acceptance as permanent — “we decided this in 2019, end of discussion” — fail to revisit decisions when context changes. The supersession discipline exists precisely to allow revision; using it is normal and healthy.
12.6 Retroactive ADRs Without Original Context
Documenting old decisions retroactively is useful but tricky. The Context section can only reflect current understanding of why the decision was made; the actual original reasoning may be lost. Mark such ADRs as “Retroactive (best reconstruction of original reasoning)” so future readers know the context is reconstruction, not contemporaneous record.
12.7 Conflating ADRs With Specifications
An ADR is not a specification for what to build. It is a record of why a structural choice was made. A team that writes ADR-style documents to specify upcoming work is conflating the artifact types. Specifications go in tickets, design docs, RFCs. ADRs come after the decision is made (or, if proposed, immediately before).
12.8 ADRs in a Vacuum
ADRs are useful when the team writes them together and reads them consistently. A single architect writing ADRs that nobody else reads produces shelfware. Adoption is a team practice; if half the team ignores the ADR folder, the practice will not stick.
13. ADR Template Appendix
A reusable template, suitable for adapting per project. Place this in docs/adr/template.md.
# ADR-NNNN: <Short Imperative Title>
## Status
<Proposed | Accepted | Rejected | Deprecated | Superseded by ADR-XXXX>
Date: YYYY-MM-DD
## Context
<What is the issue we are addressing? What forces are at play (technical,
business, organizational, regulatory)? What constraints apply? What prior
decisions does this build upon?>
## Considered Options
<Optional. List the alternatives that were considered.>
1. **Option A** — brief description, key pros and cons.
2. **Option B** — brief description, key pros and cons.
3. **Option C** — brief description, key pros and cons.
## Decision
<We will/We chose <option>. Specifically: <concrete details that pin the decision
to actionable guidance>.>
## Consequences
### Positive
- <What does this enable or improve?>
### Negative
- <What does this cost or preclude?>
### Forward-Looking
- <What conditions would prompt revisiting this decision?>
- <What follow-up decisions does this require?>
## References
- <Related ADRs by number.>
- <External documentation, papers, or articles consulted.>
- <Issue trackers, design docs, or PRs that informed the decision.>A complementary template for the auto-generated docs/adr/README.md:
# Architecture Decisions
This directory contains the project's Architecture Decision Records (ADRs). Each
record describes one significant architectural choice, its context, the decision
made, and the consequences.
## Index
| Number | Title | Status |
|--------|-------|--------|
| 0001 | <title> | Accepted |
| 0002 | <title> | Superseded by 0007 |
| ... | ... | ... |
| 0042 | <title> | Proposed |
## Process
1. To propose a decision, copy `template.md` to `ADR-NNNN-<short-title>.md`.
2. Open a pull request with status `Proposed`.
3. Reviewers comment on the PR; iterate until alignment.
4. Merge with status `Accepted`.
5. To supersede a prior decision, write a new ADR and update the prior one's
`Status` line to `Superseded by ADR-XXXX`.
## Conventions
- Use sequential numbering, never re-using a number even if an ADR is rejected.
- Never edit the body of an accepted ADR. Update only the `Status` line on
supersession.
- Keep ADRs short — typically 1–2 pages.14. Diagram — The ADR Lifecycle
flowchart LR P[("Proposed<br/>(file added,<br/>PR open)")] A[("Accepted<br/>(PR merged)")] S[("Superseded<br/>by ADR-NNN")] D[("Deprecated<br/>(no longer relevant<br/>but not replaced)")] R[("Rejected<br/>(PR closed<br/>or kept for record)")] P -->|"team agrees"| A P -->|"team disagrees"| R A -->|"context changed,<br/>new ADR written"| S A -->|"no longer applies,<br/>no replacement"| D
What this diagram shows. The five canonical statuses and the transitions between them. An ADR begins as Proposed (a file added to the repo, often via PR). The team reviews. Either the proposal is accepted (status moves to Accepted), or it is rejected (status moves to Rejected; in some teams the file is deleted, in others it is kept as a record of “we considered this and chose not to do it”). Once Accepted, the ADR’s body is immutable. The only edits permitted are to the Status line. If a future ADR supersedes this one, the status moves to Superseded by ADR-NNN. If the decision is no longer relevant but not replaced (e.g., the technology was retired and nothing replaces it), the status moves to Deprecated. The forward arrows from Accepted are the supersession discipline in graph form: changes to the system’s architecture move via new ADRs that supersede or deprecate old ones, never via in-place edits to old ADRs. The diagram is intentionally one-way for the body of the ADR (Proposed → Accepted) and reversible only for the status line (Accepted → Superseded → …). This irreversibility is the structural feature that gives ADRs their value as historical record.
15. Open Questions
- How should ADRs be organized in monorepos with hundreds of services? A single
docs/adr/for the whole repo loses the per-service locality; per-service ADR folders lose the cross-cutting view. - What is the right granularity of ADRs? “We use Postgres” is a clear ADR; but what about “we use Postgres 14 with logical replication”? Sub-decisions can either be folded into the parent ADR or split into their own. Practice varies.
- How should ADRs interact with security/compliance review? ADRs are public within the team; security decisions sometimes need restricted access.
- Are there ADR formats that better support quantitative tradeoff analysis (e.g., explicit scoring of options against criteria)? MADR has rough support; more rigorous formats exist but are heavier.
- How should AI-assisted decision-making be reflected in ADRs? When a decision is influenced by AI-generated analysis, does that show up in the ADR? (Currently most teams treat AI input as just another input, no special marking.)
- Is there value in negative ADRs — recording decisions explicitly not to do something — to head off future re-litigation?
16. See Also
- Architecture Styles vs Patterns vs Frameworks — the vocabulary that ADRs document
- Conway’s Law — ADRs reflect the team’s architectural reasoning; team boundaries shape what gets recorded
- 12-Factor App Methodology — ADRs are the artifact for documenting which factors a team has adopted, deviated from, and why
- Replicated State Machine Architecture — a foundational distributed-systems abstraction
- Microservices Architecture — most microservices migrations are documented via a chain of ADRs
- Monolithic Architecture — ADRs are equally valuable in monoliths
- Strangler Fig Pattern — ADR chains during a migration look like supersession sequences
- Distributed Monolith Anti-Pattern — frequent diagnosis surfaced by reading old ADRs against current state
- Domain-Driven Design Strategic Patterns — bounded contexts are typical ADR subjects
- System Architectures MOC
- SWE Interview Preparation MOC