Marcus Vechiato

How to Write an Architecture Decision Record (ADR)

How to Write an ADR That Your Team Will Actually Use.

If you’ve ever debated a tech choice in Slack at 4 p.m. and re‑debated it at 4 a.m., you know why ADRs exist. An Architecture Decision Record is a short, durable note that captures a significant choice, the context that shaped it, and the consequences that follow. Done well, ADRs prevent decision drift, align teams, and make future you very grateful.

What an ADR is (and isn’t)

  • It is: A concise, point‑in‑time record of one architectural decision and why you made it.
  • It isn’t: A design doc, a meeting transcript, or a dumping ground for opinions. Keep it tight; link out to deeper docs if needed.

A minimal ADR template Use a lightweight format Markdown in your repo works well:

  • Title: Specific and imperative. Example: “Adopt Managed Postgres for Production.”
  • Status and Date: Proposed, Accepted, Rejected, Deprecated, or Superseded. Include the decision date.
  • Context: The problem, drivers, constraints, and relevant background. Mention alternatives considered.
  • Decision: The choice made and the rationale in one or two paragraphs.
  • Consequences: Trade‑offs, risks, impacts, related follow‑ups, and what changes as a result.

Writing the ADR, step by step:

  1. Name the decision clearly:

    • Bad: “Database.”
    • Good: “Migrate from Self‑Hosted Postgres to Cloud‑Managed Postgres.”
  2. Capture the context briefly

    • Answer: What problem are we solving? What constraints matter (scale, latency, budget, compliance)? Which options were on the table?
  3. Explain the decision and why

    • Be explicit about your rationale: cost, risk, time‑to‑value, team expertise, operational burden. If you’re uncertain, say so, include assumptions.
  4. Spell out consequences and trade‑offs

    • What will be better? What gets worse? What do we need to do next (migrations, observability, SLAs)? The strongest ADRs illuminate the non‑obvious costs.
  5. Set the status and don’t edit history

    • When accepted, freeze the ADR. If you change direction later, write a new ADR that supersedes the old one. Treat the log as append‑only.

A concrete example

Title: Adopt Managed Postgres for Production

Status: Accepted - 2022‑11‑10

Context:

We need predictable performance and high availability for the customer billing service. Current self‑hosted Postgres requires manual upgrades and on‑call expertise we lack. We evaluated: (a) stay self‑hosted, (b) managed Postgres on Cloud X, © migrate to MySQL on Cloud X.

Decision:

Adopt Managed Postgres on Cloud X. This aligns with our team’s SQL expertise, reduces operational toil (backups, replicas, patching), and delivers HA features within budget. MySQL was rejected due to migration cost and potential query rewrites; staying self‑hosted was rejected due to reliability risks and on‑call burden.

Consequences:

  • Positive: Reduced ops overhead; automated backups; easier failover; predictable maintenance windows.
  • Negative: Higher monthly cost; vendor lock‑in; limited custom extensions.
  • Follow‑ups: Provision a staging instance; define RPO/RTO; update migration scripts; revise runbooks; set observability dashboards.

Good practices that make ADRs stick

  • Be brief and specific: two pages is plenty; one page is ideal.
  • Record alternatives: even if you discarded them quickly, list why.
  • Make ownership clear: one author drives review; anyone can comment.
  • Link out: reference design docs, tickets, benchmarks rather than duplicating.
  • Timestamp and tag: make ADRs searchable; use consistent naming.
  • Keep confidence levels honest: “High confidence on ops benefits; medium on cost projections.”

Common pitfalls to avoid

  • Vague problem statements (“It’s slow”) without metrics or constraints.
  • Skipping trade‑offs; every decision has costs, name them.
  • Editing accepted ADRs; instead, supersede with a new one.
  • Turning ADRs into debates; capture the decision, not the thread.
  • Burying ADRs in wikis; keep them alongside code where developers work.

Where to store ADRs

Put ADRs in your repo (e.g., /docs/adrs or /adr). Use filenames like 0001-adopt-managed-postgres.md, 0002-choose-graphql.md. Keeping them near code makes them part of the review and change process.

Adapting ADRs for non‑engineering audiences

If product, security, or compliance folks will read them, add a one‑paragraph summary up top and a “Stakeholder impact” bullet list. Avoid jargon; define terms.


A quick starter template you can copy

Title Status - YYYY‑MM‑DD

Context

  • Problem:
  • Drivers/Constraints:
  • Alternatives considered:

Decision

  • Choice:
  • Rationale:

Consequences

  • Positive:
  • Negative:
  • Follow‑ups:
  • Risks/Assumptions:

The payoff

ADRs don’t eliminate hard choices but they make those choices legible. Future maintainers will understand not just what you chose, but why. That context compounds into faster onboarding, clearer reviews, and fewer “Wait, who decided this?” moments.


References: