By Simeon Zimmermann

Architecture decision records: writing down why, not only what

How a development team can use short decision records to keep the reasons behind technical choices, and what to do so the habit survives past the second month.

  • Architecture
  • Teams
  • Documentation

Every codebase contains decisions that look strange from the outside. Why is there a message queue between these two services? Why does this module not use the ORM everyone else uses? Someone had a reason, and a year later nobody remembers it. The team either keeps the oddity out of fear, or removes it and finds out why it was there.

An architecture decision record (ADR) is a short text that answers one question: why did we choose this? It is written when the decision is made, stored next to the code, and never rewritten afterwards.

What an ADR contains

Michael Nygard proposed the format in 2011 in the article “Documenting Architecture Decisions”, and most templates still follow it:

  • Title: a short noun phrase, numbered. “0007 Use PostgreSQL as the only data store”.
  • Status: proposed, accepted, rejected, deprecated, or superseded by another record.
  • Context: the situation and the forces at play. Requirements, constraints, what the team knew at the time.
  • Decision: what was decided, in full sentences.
  • Consequences: what becomes easier, what becomes harder, what we now have to live with.

The template known as MADR (Markdown Any Decision Records) adds a list of the options that were considered, with their pros and cons. I like that addition, because a record that names the rejected options saves the next person from proposing them again.

A record fits on one screen. If it takes longer than an hour to write, the decision is probably not clear yet, which is useful to find out.

A short example

# 0007 Use PostgreSQL as the only data store

Status: accepted (2026-03-12)

## Context

The first release needs orders, customers, and invoices with strong
consistency. The team has three developers and no one with experience
operating a second database. We expect fewer than 50 orders per day
in the first year.

## Options considered

- PostgreSQL only
- PostgreSQL plus Redis for sessions and caching
- A document database for orders

## Decision

We use PostgreSQL for all persistent data, including sessions. We add
other stores only when a measured problem requires it.

## Consequences

- One system to back up, monitor, and learn.
- Sessions in the database add a small amount of load per request.
- If order volume grows by a factor of 100, we need to revisit caching.

Nothing in it is clever. That is the point: it records the situation, the options, the choice, and the price.

When to write one

Not every choice needs a record. A useful rule is to write one when at least one of these is true:

  • the decision is expensive to reverse (data store, authentication, hosting, a public API);
  • it affects more than one team or more than one part of the code;
  • there was a real disagreement and a reason was needed to settle it;
  • you can imagine a new colleague asking “why is it like this?” in a year.

Choosing a date library, a lint rule, or a folder name does not qualify. If the records are mostly small, nobody will read the important ones.

Life of a record

Life of a decision record: proposed, accepted, and later superseded by a newer record. Proposed Pull request is open Accepted Merged, now in force Superseded Replaced by a newer ADR
An accepted record is not edited. When the decision changes, a new record replaces it and links back.

The rule that makes this work: an accepted record is never edited. If the decision changes, write a new record, mark the old one “superseded by 0019”, and link both ways. The history of why the architecture looks the way it does stays intact, including the decisions that turned out wrong.

Where to keep them and how to review them

Keep records in the repository, for example in docs/adr/0007-use-postgresql.md, and handle them like code:

  1. The author opens a pull request that contains only the record.
  2. The team discusses in the pull request. This is where disagreement should happen, in writing, with the options in front of everyone.
  3. The record is merged as “accepted” when the people affected agree, or when the person who owns the decision has decided and the reasoning is recorded.

Two practical additions help. Put a time limit on the discussion (a week is plenty for most decisions), and name one person who decides if the group does not converge. Without both, records turn into long threads that never end.

If you want tooling, adr-tools creates and numbers files from the command line, and Log4brains turns a folder of records into a searchable site. Neither is required. A folder and a template are enough.

Why teams stop writing them

Most ADR habits die for the same few reasons:

  • The records are too long. Nobody reads two pages of background. Keep context to what a new colleague needs to follow the decision.
  • They are written after the fact, or never. Writing the record while deciding costs ten minutes. Reconstructing it later costs an argument. Retroactive records are still worth writing for the decisions people ask about most. Date them honestly.
  • Nobody links to them. Mention the record in the pull request that implements it, and in a code comment where the odd-looking choice lives.
  • The consequences section is missing. If a record only lists benefits, it is advertising. The negative consequences are what future readers need.
  • Nobody revisits them. Add a review date when the decision depends on an assumption such as traffic or team size.

Starting this week

You do not need a process meeting. Create the folder docs/adr/. Write record 0001: “We record architecture decisions in this repository”, using the template above. Then write three retroactive records for the questions new team members ask most often. After that, write a record whenever the next real decision comes up, and see whether the second one is easier than the first.

Want to talk this through for your product?

Tell me what you are building and where you are stuck. I reply personally.