Skip to content
Back to Architecture Decisions

ADR Format

The standard Markdown structure for an Architecture Decision Record.

Why

Decisions made in Slack threads and meeting notes disappear within a week. An ADR is a short Markdown file that survives team turnover, reorgs, and repo migrations. The format forces the author to state context, decision, and consequences explicitly, which is the part people actually need six months later. Without a fixed format, every ADR becomes a free-form essay and the useful sections (status, superseder) are inconsistent or missing.

When

Any time a decision has architectural impact — runtime, data store, framework, security boundary. Takes 15-30 min to write. Skip for purely cosmetic or reversible choices.

How

1. Create docs/adr/NNNN-short-title.md (NNNN = zero-padded sequence)
   - Numbering is monotonic; never reuse a number even if an ADR is rejected

2. Fill the standard sections in order:
   # NNNN. Title
   - Status: Proposed | Accepted | Deprecated | Superseded by [NNNN]
   - Date: YYYY-MM-DD
   - Context: what forces are at play, what constraints exist
   - Decision: what we decided (one sentence, bold)
   - Consequences: positive, negative, neutral effects

3. Keep Context ≥ 3 paragraphs; this is the section future-you reads most
   - Include the alternatives you considered and why each was rejected

4. Set Status=Proposed, request review, then flip to Accepted after sign-off
   - Never delete an Accepted ADR; supersede it with a new one that links back

5. Commit the ADR in the same PR as the code that implements it

Example

# 0007. Use PostgreSQL instead of MongoDB for primary store
- Status: Accepted
- Date: 2026-03-14
- Context: We need transactions and joins for the billing module.
  MongoDB lacks multi-document ACID without performance-killing workarounds.
  Team already operates Postgres for analytics. Considered: DynamoDB (rejected
  — vendor lock-in + no joins), MySQL (rejected — weaker JSON support).
- Decision: **Adopt PostgreSQL 16 as the primary transactional store.**
- Consequences:
  + Full ACID, mature tooling, one fewer datastore to operate.
  - Must define schemas up front; less flexibility than document store.
  ~ Neutral: read replicas cost similar to Mongo replica set.

Common Problems

  • ⚠Writing the Decision section without the Context — a future reader sees the 'what' but not the 'why' and cannot judge whether the decision still holds.
  • ⚠Letting ADRs accumulate as Proposed forever — the team never actually commits, so the repo has a pile of half-decisions and no source of truth.
  • ⚠Editing an old Accepted ADR in place instead of superseding it — you destroy the audit trail of how the architecture evolved.

Best Practices

  • ✓Link every ADR from the PR that implements it and from the README's architecture section — an ADR nobody can find is just a file.
  • ✓Review ADRs in a dedicated 30-min architecture sync, not buried in a general standup where nobody reads the context.
  • ✓Add a 'Supersedes' line when replacing a decision so tooling can render the decision graph automatically.

Related Resources