MODULE 4 OF 9 · FOUNDATIONS

Architecture Decision Records

30 min read 4 outcomes Interactive quiz

By the end of this module you will be able to:

  • Explain what an Architecture Decision Record is and why teams at DVLA, AWS, and Spotify use them
  • Write a complete ADR in Michael Nygard's format, including the Alternatives Considered section
  • Identify when a decision is architecturally significant and warrants an ADR
  • Describe the ADR status lifecycle from Proposed through to Superseded
Engineer reviewing technical documents at a desk (photo on Unsplash)

Real-world case · DVLA 2019 to 2022

The team that nearly undid three years of AWS migration decisions.

The Driver and Vehicle Licensing Agency (DVLA) began migrating 100 or more legacy services to AWS in 2019. The first 18 months went well. The team had institutional memory, the architects who made the foundational choices were present, and the rationale for every major decision was in people's heads.

Then the team grew. New engineers arrived from outside the programme. By late 2020, a pattern had emerged: new team members were proposing changes that contradicted decisions made in the first year. Not because the decisions were wrong, but because the newcomers did not know the constraints that had produced them. One team proposed switching from Amazon Kinesis to Apache Kafka for the streaming pipeline. The proposal was well reasoned and technically sound. But Kinesis had been chosen in ADR-012, which explained exactly why Kafka was evaluated and rejected: the regulatory requirement to keep all data within UK AWS regions, combined with the operational overhead of self-managing a Kafka cluster with the team size available at the time.

After adopting ADRs across all 47 services in the programme, the DVLA team reported that technology re-evaluation meetings took 15 minutes instead of two hours. ADR-012 answered the Kafka question before it was even fully asked.

When you join a project mid-stream, how do you know which decisions are deliberate and which are accidents?

With the learning outcomes established, this module begins by examining what an adr is in depth.

4.1 What an ADR is

An Architecture Decision Record (ADR) is a short document that captures one architecturally significant decision, the context that produced it, and the consequences it creates. The concept was named by Michael Nygard in a 2011 blog post titled "Documenting Architecture Decisions." It has since been adopted by Amazon Web Services, GitHub, Spotify, and many government digital programmes including GOVUK Pay and the NHS Digital programme.

The key distinction between an ADR and ordinary documentation is what it records. Most documentation describes what a system does. An ADR describes why it does it that way and what alternatives were rejected. This is the information that disappears fastest as teams turn over: the reasoning is rarely in the code itself and rarely survives in meeting notes.

ADRs are stored in the repository alongside the code they govern, typically in a directory named docs/decisions/ or adr/. Being version-controlled means every ADR has a commit history, can be linked from code comments, and is visible in pull request reviews.

We will keep a collection of records for architecturally significant decisions: those that affect the structure, non-functional characteristics, dependencies, interfaces, or construction techniques.

Nygard, M. (2011) - Documenting Architecture Decisions. thinkrelevance.com

Nygard's test for whether a decision warrants an ADR: does it affect structure, non-functional characteristics (quality attributes), dependencies between components, interfaces that others rely on, or construction techniques that shape what is possible? Implementation details below that threshold do not need ADRs. The test rules out most day-to-day code decisions and focuses the ADR collection on the choices that genuinely constrain future development.

Architect reviewing ADR decision records stored as Markdown files next to the code they describe
ADRs are stored as plain Markdown files next to the code they describe. Keeping them in the repository ensures they are version-controlled, searchable, and reviewable alongside pull requests.

With an understanding of what an adr is in place, the discussion can now turn to when to write an adr, which builds directly on these foundations.

4.2 When to write an ADR

Write an ADR when the decision is difficult or expensive to reverse, affects more than one team or component, involves meaningful trade-offs between quality attributes, has compliance or audit implications, or will be questioned by a future engineer who does not have today's context. These five criteria come from Nygard's original formulation and from practitioner experience across large programme delivery.

Do not write an ADR for implementation decisions where the reasoning is obvious from the code, reversible with low effort, and confined to a single team. Choosing a code formatter, a test runner, or a date utility library does not warrant an ADR. Choosing whether to build a monolith or microservices does.

The DVLA programme used a rule of thumb: if a new engineer reading the code six months later would likely ask "why is it this way?", an ADR should exist to answer that question before it is asked.

Write an ADR for: selecting a database technology; adopting an event-driven communication model; choosing a deployment topology; establishing an authentication strategy; selecting a cloud provider or service; adopting a framework that shapes all future development in a domain.

Do not write an ADR for: choosing a linting tool; selecting a logging library used only within one service; picking a utility library for date handling; defining variable naming conventions.

Borderline cases: introducing a new programming language for one service (write one if other teams interact with it); choosing between two ORMs with similar capabilities (write one if the choice has cross-team consequences or compliance implications).

Common misconception

ADRs are just meeting minutes that describe what was discussed.

ADRs and meeting minutes are structurally different. Meeting minutes describe discussions. ADRs capture a single decision together with its context, the options that were rejected, and the consequences. An ADR is not a record of process; it is a record of reasoning. A future engineer reading an ADR should understand not just what was decided but why the alternatives were not chosen.

With an understanding of when to write an adr in place, the discussion can now turn to the nygard adr format, which builds directly on these foundations.

4.3 The Nygard ADR format

Nygard's original format has five sections. The MADR (Markdown Architectural Decision Records) format maintained by the ADR GitHub organisation extends it with an explicit Options Considered section. Both formats are in widespread use. The five-section Nygard format is the foundation.

Title and number. A short, imperative phrase that names the decision. "ADR-001: Use PostgreSQL as Primary Database." The number ensures the decision can be referenced without ambiguity from code comments and from other ADRs.

Status. Proposed, Accepted, Deprecated, or Superseded. Status makes the lifecycle of the decision visible. An ADR superseded in 2024 should reference the ADR that replaced it: "Superseded by ADR-019."

Context. The situation that necessitated a decision. The technical constraints, business requirements, team capabilities, and time pressures at the moment of the decision. This section is the most important for future engineers: it is what lets them evaluate whether the conditions that produced the decision still apply.

Decision. What was decided, stated clearly and directly. "We will use PostgreSQL 15 as our primary database." One sentence, active voice. Not "we considered several options."

Consequences. What becomes easier and what becomes harder. Both positive and negative consequences. "Strong ACID consistency for order processing" is a positive consequence. "Horizontal write scaling requires sharding complexity" is a negative one. Recording both is what makes the ADR honest.

ADRs are a lightweight mechanism for capturing the architectural decisions made on a project. They are typically stored alongside the code in a docs/adr directory and checked into version control.

ThoughtWorks Technology Radar - Architecture Decision Records, Adopt (2020)

ThoughtWorks moved ADRs to the Adopt ring of its Technology Radar in 2020, having observed them at Assess and Trial since 2016. The Adopt classification means the technique is recommended for most teams without reservation. ThoughtWorks noted that teams using ADRs reported faster onboarding and fewer regression debates during system evolution.

Loading ADR explorer...

With an understanding of the nygard adr format in place, the discussion can now turn to adr status lifecycle, which builds directly on these foundations.

4.4 ADR status lifecycle

An ADR begins as Proposed when a decision is being evaluated. It moves to Accepted once the team agrees on it. It may later become Deprecated if the decision is no longer relevant but has not been replaced by a new one. It becomes Superseded when a new ADR replaces it.

The governance principle that prevents ADR collections from becoming misleading: never modify an accepted ADR to change its decision. Instead, write a new ADR that supersedes it and explains why the previous decision no longer applies. This preserves the complete reasoning history. A team looking at the codebase in 2030 should be able to trace the chain: ADR-003 was accepted in 2020, superseded by ADR-017 in 2023 when the compliance requirement changed.

The DVLA programme used the adr-tools CLI tool to manage ADRs. The tool creates numbered files, updates status fields, and records supersession links automatically.

ADRs must be written at the moment of decision. A decision recorded a month later often loses the context that made it right. Teams that wait until they have "time to write documentation" typically never write ADRs at all.

Common misconception

ADRs should be written retrospectively once the architecture is stable.

Architecture is never stable enough for this to work in practice. Retrospective ADR writing produces documents that record what was decided but lose the reasoning: the constraints, the rejected alternatives, the business pressures, and the team capabilities at the time. An ADR written six months after the decision is often a rationalisation, not a record. Write ADRs at the moment of decision, when the context is present.

With an understanding of adr status lifecycle in place, the discussion can now turn to storing, discovering, and avoiding common mistakes, which builds directly on these foundations.

4.5 Storing, discovering, and avoiding common mistakes

The standard location for ADRs is a docs/decisions/ or doc/adr/ directory in the repository root. Keeping ADRs in the repository rather than in a separate wiki ensures they are version-controlled, survive repository migrations, appear in code search, and are visible during code review.

The adr-tools CLI, created by Nat Pryce, provides commands for creating new ADRs with auto-incremented numbers, linking supersession chains, and listing the current status of the entire ADR collection. It outputs plain Markdown files that require no special tooling to read.

The most common ADR mistakes:

Writing too many ADRs. Recording implementation-level decisions dilutes the collection. When every commit has an associated ADR, the significant decisions disappear in noise. Use Nygard's five criteria to filter.

Omitting the Consequences section. Most teams write the Context and Decision sections but skip Consequences. This produces ADRs that record what was decided without recording what it costs. Future engineers see the decision but not the trade-off.

Missing Alternatives Considered. The Alternatives section is the single most valuable part of an ADR and the most frequently omitted. When a future engineer proposes exactly the alternative that was rejected, the ADR should answer their question before the meeting begins. Without it, the team relitigates analysis that was already completed.

Team collaborating around architecture decision documents and design records on a table
ADRs make architectural discussions explicit and asynchronous. When the reasoning is written down, new team members can participate in decision-making without attending every meeting.

With an understanding of storing, discovering, and avoiding common mistakes in place, the discussion can now turn to adr tooling in practice, which builds directly on these foundations.

ADR tooling in practice

The adr-tools CLI automates ADR file management. It creates numbered files, links supersession chains, and lists current ADR status. Here is a typical workflow for a team adopting ADRs.

Loading terminal...
Loading terminal...
Loading challenge...
4.6 Check your understanding

A new engineer joins the DVLA AWS migration team and proposes switching from Amazon Kinesis to Apache Kafka. ADR-004 from 2021 exists for the Kinesis decision. What should happen first?

Which of the following decisions most clearly meets Nygard's criteria for an ADR?

An ADR is marked as Accepted in 2021. In 2024, the team decides the decision no longer applies and the system should be changed. What is the correct approach?

Key takeaways

  • An ADR captures one architecturally significant decision together with the context that produced it and the consequences it creates, not just the decision itself.
  • Nygard's five sections are Title and number, Status, Context, Decision, and Consequences. The Alternatives Considered section (from MADR) is the most frequently omitted and the most valuable for preventing decisions from being relitigated.
  • Write ADRs when the decision is hard to reverse, affects multiple teams, involves trade-offs between quality attributes, or has compliance implications. Do not write ADRs for implementation-level choices.
  • Never modify an accepted ADR to change its decision. Write a new ADR that supersedes it and explains why the context changed.
  • ADRs must be written at the moment of decision and stored in the repository. Retrospective ADR writing loses the context that made the decision right at the time.
  • The adr-tools CLI automates numbering, supersession linking, and table-of-contents generation for Markdown ADR collections.

Standards and sources cited in this module

  1. Nygard, M. (2011). Documenting Architecture Decisions. thinkrelevance.com.

    The original blog post that named and defined ADRs. Nygard's five-section format and the scope criteria in Section 4.2 are taken directly from this source.

  2. ADR GitHub Organisation. MADR: Markdown Architectural Decision Records.

    The maintained ADR template standard that extends Nygard's format with explicit Options Considered and Positive/Negative Consequences subsections. Referenced in Section 4.3.

  3. Keeling, M. (2017). Design It! From Programmer to Software Architect. Pragmatic Bookshelf.

    Chapter 12: Document Decisions

    Provides practical guidance on writing decisions that preserve reasoning rather than just recording outcomes. Extends Nygard's format with decision driver prioritisation.

  4. Pryce, N. adr-tools. GitHub repository.

    The reference implementation CLI for creating and managing ADR Markdown files. Used in the terminal simulation in Section 4.5.

  5. ThoughtWorks. Technology Radar Volume 22 (2020). Architecture Decision Records.

    The source for the Adopt classification of ADRs referenced in Section 4.3. ThoughtWorks observed ADR adoption reducing onboarding time and decision regressions across multiple client programmes.

  6. Hohpe, G. (2020). The Software Architect Elevator. O'Reilly Media.

    Chapter 5: Architecture Documents

    Provides the organisational context for ADR value: decisions recorded in the repository outlive the engineers who made them and bridge technical and business stakeholders across team turnovers.

What comes next: ADRs capture decisions. The most common first architectural decision is how to organise code into layers. Module 5 introduces layered architecture - the pattern that separates presentation, business logic, and data access into independent tiers with a strict dependency rule.

Module 4 of 22 in Foundations