View Categories

Architecture Decision Records (ADRs)

3 min read

The “Tribal Knowledge” Trap #

The most dangerous phrase in a startup is: “Ask Bob, he built that system 3 years ago.” Eventually, Bob quits. When Bob leaves, the logic leaves with him. The new team looks at the code, sees a weird implementation (e.g., “Why are we using XML here?”), and assumes Bob was an idiot. They rewrite it, only to hit the exact same edge case that forced Bob to use XML in the first place.

The Logic Check: If your architectural decisions are buried in Slack threads, email chains, or a dusty Confluence page that nobody reads, they do not exist. You need a system that lives with the code, evolves with the code, and is reviewed like code.

The Core Logic: The Immutable Record #

An Architecture Decision Record (ADR) is a short text file that captures a single design decision. The key insight is that an ADR is Immutable.

  • You don’t update an old ADR.
  • You write a new ADR that “Supersedes” the old one.
  • This creates a history log. You can trace the evolution of the system from 2020 to 2025.

The Nygard Format: Michael Nygard (author of Release It!) defined the standard structure that every Architect should use:

  1. Title: “ADR 001: Use Postgres for User Data”
  2. Status: Accepted / Deprecated / Superseded
  3. Context: The “Why.” (e.g., “We need ACID compliance.”)
  4. Decision: The “What.” (e.g., “We will use PostgreSQL 14.”)
  5. Consequences: The “Trade-off.” (e.g., “Positive: Data safety. Negative: Harder to shard than Mongo.”)

Architecture Diagram: The Documentation Workflow #

Documentation should not be a separate “Phase.” It should be part of the Pull Request.

graph TD
    Dev[Developer] -- "Proposes Change" --> PR[Pull Request]
    PR -- "Includes Code" --> Code[Source Code]
    PR -- "Includes Decision" --> ADR[ADR-005.md]
    
    Reviewer[Architect] -- "Reviews Logic" --> ADR
    
    subgraph "The Repository"
    Repo[Git Repo]
    Repo --> Src[/src/]
    Repo --> Docs[/docs/adr/]
    Docs --> File1[001-init.md]
    Docs --> File2[002-use-kafka.md]
    Docs --> File3[005-change-to-sqs.md]
    end
    
    PR -- "Merge" --> Repo
    
    note[The Logic lives next to the Code.]

The Decision Matrix: When to Write an ADR? #

Not every decision needs a document. Do not write an ADR for “Fixing a typo.”

ScenarioWrite ADR?Why?
Adding a LibraryNo (Usually)Unless it’s a massive framework (e.g., React vs. Vue), just put it in the PR description.
Changing DatabaseYESThis is hard to reverse. Future devs need to know why.
New API StandardYES“We are switching from REST to GraphQL.” The whole team needs to align on this.
Structuring CodeYES“We will use Hexagonal Architecture.” Defines the pattern for years.
Quick HackYES“We are intentionally bypassing security for 2 weeks to hit a deadline.” Document the debt.

Real-World Case Study: The UK Government (GDS) #

The UK Government Digital Service (GDS) manages thousands of developers across massive, slow-moving agencies.

  • The Problem: They had massive “Enterprise Architecture” PDFs that were 200 pages long. Nobody read them. Teams built incompatible systems.
  • The Fix: They standardized on ADRs stored in Git.
  • The Result: When a new team started a project, they cloned the repo and read the /docs/adr folder. In 15 minutes, they understood the 5 years of decisions that led to the current state.
  • Tooling: They use simple CLI tools (like adr-tools) to generate the files automatically: $ adr new "Use S3 for document storage"

Conclusion #

Code tells you how. ADRs tell you why. Writing an ADR takes 15 minutes. Debugging a system where you don’t understand the constraints takes weeks. Stop treating documentation as a chore. Treat it as a “Time Capsule” for your future self.