Simple Enough Blog logo
  • Home 
  • Projects 
  • Tags 

  •  Language
    • English
    • Français
  1.   Blogs
  1. Home
  2. Blogs
  3. ADR (Architecture Decision Record): documenting decisions that matter

ADR (Architecture Decision Record): documenting decisions that matter

Posted on February 23, 2026 • 7 min read • 1,357 words
ADR   Architecture   Engineering   Helene   Documentation  
ADR   Architecture   Engineering   Helene   Documentation  
Share via
Simple Enough Blog
Link copied to clipboard

An ADR is not “yet another architecture document”: it’s a short note that captures context, the decision, and its consequences. Used well, it prevents repetitive debates, speeds up alignment, and makes choices durable.

On this page
I. Where does the term ADR come from, and why “Nygard-style”?   1) A quick historical note   2) What is an ADR, exactly?   II. When to write an ADR (and when not to)   Write an ADR if…   Don’t write an ADR if…   III. The “Nygard-style” format: simple and durable   a) Context — what situation are we deciding in?   b) Decision — what are we choosing?   c) Status — where are we in the lifecycle?   d) Consequences — what does this decision imply?   e) Alternatives considered — what did we reject, and why?   f) Execution plan — optional, but often decisive   IV. How to keep ADRs lightweight   Rule 1 — One ADR = one decision (and only one)   Rule 2 — Keep ADRs close to the code   Rule 3 — Treat ADRs like code   Rule 4 — Replace decisions cleanly   V. A complete example (a realistic mini ADR)   VI. Common pitfalls   Conclusion   Useful links  
ADR (Architecture Decision Record): documenting decisions that matter
Photo by Helene Hemmerter

Engineering teams spend a lot of time discussing, arbitrating, choosing… and then forgetting why they made certain decisions.
The outcome is familiar:

  • the same debates come back every three months,
  • decisions get challenged without the original context,
  • onboarding depends on “the people who know,”
  • and unnecessary migrations are born from a simple loss of memory.

An ADR (Architecture Decision Record) exists to avoid that. It’s not a “big architecture doc,” nor a requirements spec: it’s a short note that captures an important decision, with just enough context to keep it understandable and reusable.


I. Where does the term ADR come from, and why “Nygard-style”?  

1) A quick historical note  

ADRs (Architecture Decision Records) became popular thanks to a post by Michael Nygard, Documenting Architecture Decisions (November 15, 2011), where he proposes a deliberately lightweight approach: recording an “architecturally significant” decision with just enough context to keep it understandable over time.

The template often referred to as the “Nygard ADR” (Title / Status / Context / Decision / Consequences) comes directly from that proposal and has been widely adopted by the community as a reference format.

In practice, you can say Nygard primarily popularized and standardized a simple method to preserve decision memory—hence why his name still comes up whenever people talk about ADRs.

2) What is an ADR, exactly?  

An ADR is a document (often one page max) that answers three questions:

  1. In what context are we making this decision?
  2. What are we deciding?
  3. What consequences are we accepting?

The goal isn’t to produce a “pretty” document. The goal is to make a decision:

  • replayable (you understand the reasoning),
  • stable (you avoid re-running the debate),
  • healthily contestable (if you change it, you know what you’re changing and why).

II. When to write an ADR (and when not to)  

Write an ADR if…  

  • the decision impacts multiple components / teams,
  • the cost of change is high (migration, data, security),
  • the decision will be re-read in 6–12 months,
  • a rejected option will inevitably come back in future discussions,
  • the decision touches “principles”: standardization, observability, patterns, etc.

Typical examples:

  • choosing a database (PostgreSQL vs DynamoDB),
  • monorepo organization (Nx vs Bazel vs Turbo),
  • authentication strategy (OIDC, SSO, tokens),
  • event format / schema (Avro/Protobuf/JSON),
  • deployment or environment conventions.

Don’t write an ADR if…  

  • it’s a trivial decision (e.g., “rename a variable”),
  • it’s reversible in 10 minutes,
  • it’s purely local to a file or module,
  • it won’t survive the week.

An ADR is not a control system. It’s a memory tool for decisions that matter.


III. The “Nygard-style” format: simple and durable  

The approach popularized by Michael Nygard aims for a short format.

a) Context — what situation are we deciding in?  

Context explains why this topic exists now.
It should contain just enough information for a future reader to understand the constraints at the time.

  • scope (system, team, project),
  • current state (“today we do X”),
  • constraints (time, budget, security, legacy, skills),
  • goals (what we’re trying to optimize).

Example:
“We deploy a Go service on Kubernetes. CI builds take ~18 minutes. We want faster feedback without losing reproducibility or significantly increasing local complexity.”


b) Decision — what are we choosing?  

The decision should be readable at a glance: short, clear, unambiguous.

  • selected option,
  • exact scope (included / excluded if needed),
  • owner (who drives implementation).

Example:
“We adopt remote caching + ‘affected’ task execution for CI (option B) to reduce average pipeline time.”


c) Status — where are we in the lifecycle?  

A decision has a life. Status prevents “ghost ADRs.”

  • Proposed | Accepted | Rejected | Deprecated | Superseded (by ADR-XXXX)

Example:
“Status: Proposed (to be validated after a PoC on one service).”


d) Consequences — what does this decision imply?  

This is the “honest” part. You write what you gain and what you accept losing.

  • expected benefits,
  • trade-offs,
  • risks,
  • impacts (docs, onboarding, maintenance, tooling).

Example:

  • faster feedback, smoother PR flow
  • more complex initial setup
  • risk of incorrect cache hits → need safeguards
  • requires setup docs + continuous measurement of gains

e) Alternatives considered — what did we reject, and why?  

The goal isn’t to prove you were “right.”
The goal is to make options visible and document why they didn’t meet the criteria.

  • Option A: standard CI cache (limited / inconsistent gains)
  • Option C: Docker layer caching (forces Docker locally / adds friction)

Example:
“We did not choose Docker layer caching because it creates a strong dependency on local Docker and complicates the developer experience.”


f) Execution plan — optional, but often decisive  

Many teams stop at Context/Decision/Consequences.
Adding 4–6 lines turns the ADR into an operational decision (otherwise it “sleeps”).

Next steps should be: short, assigned, verifiable.

  • action checklist,
  • owner,
  • rough deadline,
  • validation criterion,
  • rollback if the risk is high.

Example:

  • PoC on one service (Hélène, Friday)
  • Measure CI time before/after (average, variance, failure rate)
  • Document setup + cache invalidation rules (README)
  • Decide rollout if gain > 30% and stable (otherwise rollback)

IV. How to keep ADRs lightweight  

An ADR rarely fails because the format is bad. It fails because:

  • nobody knows when to write one,
  • nobody reads them,
  • nobody updates them when they’re replaced.

Here are practices that work.

Rule 1 — One ADR = one decision (and only one)  

Don’t mix “DB choice” + “repo conventions” + “event format” in a single doc.
If you need to do that, you probably have multiple decisions.

Rule 2 — Keep ADRs close to the code  

The most common approach: a docs/adr/ folder in the repo.
Naming examples:

  • docs/adr/0001-use-postgresql.md
  • docs/adr/0002-ci-remote-cache.md

Numbering makes references stable.

Rule 3 — Treat ADRs like code  

A good routine:

  • the ADR is a PR,
  • it gets reviewed,
  • it gets accepted / rejected like everything else.

You can even request: “if you disagree, propose an alternative and its consequences.”

Rule 4 — Replace decisions cleanly  

When a decision changes:

  • the original ADR becomes Superseded by ADR-00XX,
  • the new ADR explains the new context (often different).

This discipline avoids contradictory documentation.


V. A complete example (a realistic mini ADR)  

# ADR-0002 — CI: Remote cache + affected tasks

Status: Accepted
Date: 2026-02-23
Owner: Hélène

## Context
Our Go services run on Kubernetes. CI pipelines average 18 minutes.
We want faster feedback without forcing Docker locally and without losing reproducibility.

## Decision
Adopt remote caching plus "affected-only" task execution for CI.
Scope: one service first, then extend to the monorepo if results are stable.

## Consequences
+ Faster feedback; fewer stalled PRs
+ Better scalability as the repo grows
- Initial setup complexity (cache backend, auth)
- Risk of incorrect cache hits → need safeguards and invalidation rules

## Alternatives considered
A) Standard CI cache: limited gains, inconsistent
C) Docker layer caching: adds local Docker dependency and friction

## Execution plan
- [ ] PoC on one service (Hélène, Friday)
- [ ] Measure before/after (avg, variance, failure rate)
- [ ] Write setup + invalidation rules (README)
- [ ] Rollout if gain > 30% and stable; rollback otherwise

VI. Common pitfalls  

“We write ADRs for everything”

  • Result: nobody reads them, and the team starts hating the tool.
  • In short: keep ADRs for decisions with a high cost of change.

“We write the ADR after the fact”

  • Result: post-hoc justification, not a healthy debate.
  • In short: write the ADR during the decision (PR + comments).

“The ADR replaces discussion”

  • Reality: no. The ADR mainly replaces forgetting.
  • In short: discuss when needed, then crystallize the decision in the ADR.

“We don’t know whether it’s still true”

  • In short: use Status + Superseded and keep an index.

Conclusion  

ADRs should serve the team—not the other way around.

A good sign your ADRs are working:

  • a newcomer can answer “why do we do it this way?” in two minutes,
  • a “we’ve already had this debate” conversation ends with an ADR link,
  • the team debates criteria (context/consequences) rather than implicit preferences.

Useful links  

  • Foundational ADR article (Michael Nygard, 2011)
  • ADR templates (adr.github.io) — ready-to-use models, including the “Nygard” template
  • Working Remote: Freedom, Efficiency… and the Conditions for Success — blog post
 DevOps Cycle or a Misunderstanding of the Role?
Working Remote: Freedom, Efficiency… and the Conditions for Success 
  • I. Where does the term ADR come from, and why “Nygard-style”?  
  • II. When to write an ADR (and when not to)  
  • III. The “Nygard-style” format: simple and durable  
  • IV. How to keep ADRs lightweight  
  • V. A complete example (a realistic mini ADR)  
  • VI. Common pitfalls  
  • Conclusion  
  • Useful links  
Follow us

We work with you!

   
Copyright © 2026 Simple Enough Blog All rights reserved. | Powered by Hinode.
Simple Enough Blog
Code copied to clipboard