An architecture decision record is a short document capturing one decision, its context and its consequences, kept in the repo beside the code
Code shows what was decided. It rarely shows why, or what else was on the table. Those reasons end up in someone’s head, a chat log or a closed pull request, and an agent starting a fresh session can read none of them. A decision record puts them in the repo.
Definition#
Martin Fowler defines an architecture decision record (ADR) as “a short document that captures and explains a single decision relevant to a product or ecosystem” (Architecture Decision Record, 2026). The form comes from Michael Nygard’s Documenting Architecture Decisions (2011), which gives each record five parts:
- title: a numbered noun phrase naming the decision
- status: proposed, accepted, deprecated or superseded
- context: the forces in play, including what’s already fixed
- decision: what was chosen, in full sentences
- consequences: what follows from it, including what gets harder
Most templates since add the options considered. Fowler also suggests a confidence level, and what change in circumstances should prompt a second look.
An example#
A record for a decision most final projects have to make:
# 0002. Store data in SQLite on the Fly volume
Status: accepted
## Context
The app runs on one small Fly machine with one volume, as fly.toml fixes.
Messages and rooms must survive a redeploy. Expected load is one class.
## Options
- SQLite on the volume: no second service, and a backup is a file copy. Only one
machine can write to it.
- Hosted Postgres: survives scaling out, but it's a second service to run, pay
for and connect to.
- Server memory: the least code, and lost at every restart and deploy.
## Decision
SQLite on the volume, through the framework's ORM, with migrations applied when
the server boots.
## Consequences
The app can't run on a second machine without moving its data. Migrations must
run at boot, because Fly's release_command machine has no volume. Moving to
Postgres later means a data export and a record superseding this one.
Give the consequences the most care. The next person, or session, to touch the code needs to know what the choice ruled out, and a record that lists only benefits won’t tell them.
How they’re kept#
- one file per decision, numbered in sequence: Fowler’s example is
doc/adr/0001-htmx-for-active-web-pages.md - in the repo it applies to, so it’s versioned and reviewed with the code it explains
- never edited once accepted: a changed mind is a new record, and the old one’s status becomes superseded, with a link to its replacement
- proposed first when you want it reviewed, by your pod, a tutor or an agent arguing the other side
adr-tools adds adr new and handles the
numbering and superseding links.
Backlog.md has a built-in
backlog decision create, which writes to backlog/decisions/.
What gets one#
A decision that is expensive to reverse, or that someone will ask about later. In a final project that’s the stack, what counts as a person, what persists and for how long, and how a change reaches everyone else. A library you could swap out in an afternoon, or a UI tweak, doesn’t need one; the commit message is enough.
The final project suggests them
for the stack case in PROCESS.md, which can link to a record rather than
restate it, and All at once asks you to write one
down.
With an agent#
Records help at two points in a session.
Before the decision, ask for options rather than an answer. An agent asked to “add a database” picks one and builds it, and the choice is buried in the diff. Asked for options, it lays out trade-offs you can judge:
lay out three options for where this app stores rooms and messages, with what each costs on one Fly machine. Don’t pick one and don’t write code yet
For a choice that depends on what you want, such as the stack, have it ask the questions instead:
read my README, then quiz me one question at a time about what this app needs: how many people at once, what has to persist, how fast updates travel. Give each option’s pros and cons. Don’t recommend a stack until I’ve answered
Then have it draft the record for the one you choose, with the options you ruled out, and check that the consequences say what gets harder.
After the decision, point CLAUDE.md at the records, so a fresh session
reads them before it proposes something they already rule out:
## Decisions
Architecture decisions live in `doc/adr/`, one numbered file each. Read them
before proposing a change to the stack, storage or data model. To change one,
write a new record that supersedes it.
Further reading#
- Nygard (2011): the original post and format, and still the shortest explanation
- Fowler (2026): status, superseding, confidence and where records live
- adr.github.io: templates, including MADR, and a list of tools
- joelparkerhenderson/architecture-decision-record: many templates and worked examples