Skip to content

Web Development · Architecture

Architecture Decision Records: Lightweight Docs That Survive Team Turnover

An Architecture Decision Record captures why a technical choice was made, not just what was decided. One page per decision, stored in the repo, reviewed in PRs. Here's the format and how to make it stick.

Anurag Verma

Anurag Verma

7 min read

Architecture Decision Records: Lightweight Docs That Survive Team Turnover

Sponsored

Share

Six months into a project, someone asks why the team picked PostgreSQL over MySQL. Nobody remembers. The person who made the call left the company. The Slack message that explained it is buried somewhere in a channel archive. The decision is now tribal knowledge that doesn’t live anywhere.

This is the problem Architecture Decision Records (ADRs) solve. They’re short documents (typically one to two pages) that record a technical decision, the context that led to it, and the reasoning. They live in the repository, so they travel with the code. They’re written when the decision is made, so the reasoning is fresh.

The concept comes from Michael Nygard’s 2011 blog post. It’s been refined in practice over many years and has become standard in teams that care about long-term maintainability.

What an ADR Contains

The minimal viable ADR has four parts:

Title. A short description of the decision. Start with “Use” or “Adopt” or “Replace” to make it scannable in a directory listing. “Use PostgreSQL for primary data storage” is better than “Database decision.”

Context. The situation that forced this decision. What were the requirements? What were the constraints? What alternatives existed? This is the hardest part to write later. The context is obvious now and invisible in six months.

Decision. The actual choice. One sentence or a short paragraph. Be specific.

Consequences. What changes as a result. What becomes easier. What new problems this creates. What the team needs to accept. ADRs shouldn’t oversell the chosen option; noting the downsides is part of what makes them trustworthy.

A simple format that works (the MADR format, for Markdown Architecture Decision Records):

# Use PostgreSQL for Primary Data Storage

## Status
Accepted — 2026-04-12

## Context
We need a relational database for the main application. The team has strong
experience with relational databases. The data model has clear relationships
between entities. We don't have specialized requirements (time series, graph,
document) that would push toward a specialized database.

Considered: PostgreSQL, MySQL, SQLite, MongoDB.

SQLite is ruled out: we need concurrent write access from multiple app processes.
MongoDB is ruled out: we don't have a document-centric data model, and the team
would need time to build expertise. MySQL is a close match.

## Decision
We will use PostgreSQL 16 as the primary relational database.

PostgreSQL's JSON support, full-text search, window functions, and extension
ecosystem (particularly pgvector for future AI features) give it a meaningful
edge over MySQL for our planned feature set. The team has more PostgreSQL
experience than MySQL.

## Consequences
- All new developers need PostgreSQL installed locally; add to onboarding docs.
- We can use PostgreSQL-specific features (JSONB, row-level security, pgvector).
- MySQL-only tools won't be compatible; confirm any third-party integrations
  support PostgreSQL before adopting.
- Migration to a different database later would be expensive; this is a
  long-term commitment.

Where to Store ADRs

The convention is docs/decisions/ or docs/adr/ in the repository root. Files are named with a sequential prefix and a slug:

docs/decisions/
  0001-use-postgresql-for-primary-storage.md
  0002-use-graphql-for-api-layer.md
  0003-replace-graphql-with-rest-trpc.md
  0004-use-redis-for-session-storage.md

The sequential numbering lets you reference decisions by number in code comments or PR descriptions: “see ADR-0003 for why we moved off GraphQL.”

Some teams use a docs/adr/ directory with an adr-log.md index file that lists all decisions in reverse chronological order. This is useful if the directory gets long.

ADRs Don’t Freeze Decisions

When a decision is reversed or replaced, you don’t edit the old ADR. You write a new one that supersedes it.

In ADR-0003 above, we replaced GraphQL with tRPC. The original ADR-0002 still exists. ADR-0002 gets a status update to “Superseded by ADR-0003.” ADR-0003 references ADR-0002 in its context.

## Status
Superseded by [ADR-0003](0003-replace-graphql-with-rest-trpc.md) — 2026-05-20

This creates a timeline of decisions that shows how the architecture evolved and why. Someone reading the repo three years from now can trace the reasoning through the whole sequence, not just see the current state.

Reviewing ADRs in Pull Requests

Writing an ADR for a significant architectural change and including it in the PR creates a forcing function. It makes the decision explicit before the code lands. Reviewers can comment on the reasoning, not just the implementation.

A lightweight rule that works: any PR that introduces a new external dependency, changes the deployment topology, or makes a choice that would be expensive to reverse should include an ADR.

Not every PR needs one. Adding a utility function doesn’t warrant an ADR. Switching from REST to tRPC across the entire API layer does.

The PR review is when alternatives get scrutinized and the context gets written down correctly. Once merged, the ADR is the record.

What ADRs Don’t Cover

ADRs record significant choices, not every technical decision. They’re not:

Runbooks or how-to guides. “How to deploy to production” belongs in a separate operations doc.

Design docs. A 20-page design document for a complex feature serves a different purpose. ADRs are one to two pages, not full specs.

Meeting notes. The decision goes in the ADR; the discussion that led to it can be referenced but doesn’t need to be reproduced in full.

Obvious choices. “Use ESLint for linting” probably doesn’t need an ADR. “Switch from ESLint 8 to Biome” might, depending on what changed.

The overhead should be low enough that writing an ADR doesn’t feel like bureaucracy. If a decision takes a week of discussion, the ADR takes 20 minutes to write. That’s a good ratio.

Tools for Browsing ADRs

For small repositories, a folder of Markdown files is enough. For larger ones, a few tools make them easier to navigate:

adr-tools is a shell script collection that creates and links ADRs from the command line:

npm install -g adr-tools
adr init docs/decisions
adr new "Use PostgreSQL for primary data storage"
adr supersede 2 "Replace GraphQL with REST and tRPC"

Log4brains renders a browsable static site from your ADR directory. You run it locally or deploy it as part of your internal docs:

npx log4brains preview

For most teams, the Markdown files plus GitHub’s file browser are sufficient. Tools add value when the ADR directory gets into the dozens and navigation becomes a real friction point.

Starting From Zero on an Existing Codebase

If your project is already running and has no ADRs, the temptation is to back-fill decisions retroactively. This is worth doing for a handful of key decisions but gets tedious quickly.

A practical approach: write ADRs for the three to five decisions that new developers ask about most often. Then start writing them prospectively for new decisions going forward.

The questions new developers ask are a proxy for what’s not obvious from the code alone. If every new hire asks “why are we using Redis for sessions instead of cookies?”, that’s an ADR waiting to be written.

An ADR Template for Copy-Paste

# [Short noun phrase describing the decision]

## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXXX]
Date: YYYY-MM-DD

## Context
[The situation that forced this decision. What requirements and constraints
are in play? What options were considered? Why does this decision need to
be made now?]

## Decision
[The choice made. Be specific. One to three paragraphs.]

## Consequences
[What becomes true after this decision. List both positive outcomes and
accepted downsides or new constraints.]

Keep it short. An ADR that takes 30 minutes to write is an ADR that gets written. One that requires a full afternoon tends to get skipped.

Why This Works

The value of ADRs isn’t the documentation. It’s the practice of writing them. Forcing a decision into prose reveals gaps in the reasoning. If you can’t explain why you chose option A over option B in two paragraphs, you might not have fully thought it through.

Teams that write ADRs tend to make more deliberate decisions because the decision is going to be written down and reviewed. The documentation is a side effect of better decision-making.

For agencies building on behalf of clients, ADRs have an additional value: they’re part of a handoff package. When you deliver a project, a client who can read through your key decisions understands the architecture and can make informed choices about future development, even after your engagement ends.

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored