How to write a technical decision record
How to write architecture decision records: where ADRs came from, Nygard vs. MADR vs. Y-statements, a copy-paste template, and a full worked example.
By Lance King · · 10 min read
Six months from now, someone on your team will open a file, frown, and ask, “Why on earth did we do it this way?” A technical decision record is the answer waiting for them. This guide is for engineers and tech leads who want a lightweight habit for writing down important decisions, and for founders who are tired of the same debate coming back every quarter. You’ll get the history, the main formats, a template you can paste into your repo today, and a complete worked example.
The short answer
Choose the Nygard format if you want the simplest thing that works: five short sections, one page, no tooling required.
Choose MADR if you usually weigh several options and want a consistent place for each option’s pros and cons, plus metadata like who decided and who was consulted.
Choose Y-statements if you want a one-sentence summary of each decision, either on its own for small calls or at the top of a longer record.
Whatever you choose, store records next to the code, number them, never edit an accepted one, and supersede it with a new record when you change your mind.
What a decision record is (and where it came from)
An architecture decision record, or ADR, is a short document that captures one significant decision, the context that led to it, and its consequences. The collection of all your ADRs is called a decision log. “Technical decision record” is a broader name for the same idea; plenty of teams use ADRs for decisions that aren’t strictly architecture, like picking a vendor or a testing strategy.
The format traces back to Michael Nygard’s November 2011 post “Documenting Architecture Decisions.” His argument was that agile teams are “not opposed to documentation, only to valueless documentation,” and that big design documents go stale, while small, modular records have “at least a chance at being updated.” He proposed a handful of sections, numbered files kept in the repository, and records about “one or two pages long,” written “as if it is a conversation with a future developer.”
The idea spread. Martin Fowler’s site, Microsoft’s Azure Well-Architected Framework, and AWS Prescriptive Guidance all now describe ADRs in similar terms, and the community site adr.github.io collects templates and tools.
What actually matters
Whatever format you pick, five things make a record useful years later.
- Context. The forces at play when you decided: requirements, constraints, deadlines, team skills, budget. Nygard asks for this to be written neutrally. Microsoft’s guidance warns that “a record without justification loses its value over time,” because readers can’t tell whether the decision still applies.
- Options considered. What you rejected and why. This is what stops the same alternative from being re-proposed every six months.
- The decision itself. Stated plainly, in active voice. Nygard’s convention is to start with “We will…”
- Consequences. Good and bad. Every real decision has costs, and hiding them makes the record less trustworthy.
- Status. Proposed, accepted, rejected, deprecated, or superseded. Status tells a reader at a glance whether the record still governs the work.
Two more are worth adding. Microsoft suggests recording your confidence level, since a low-confidence decision is a natural candidate for revisiting. And it helps to write down revisit triggers: the specific changes that would make you look at this again.
Comparing ADR formats
| Nygard (2011) | MADR 4.0 | Y-statement | |
|---|---|---|---|
| Length | One to two pages | One to several pages | One sentence |
| Sections | Title, Status, Context, Decision, Consequences | Context and problem statement, decision drivers, considered options, decision outcome, consequences, confirmation, pros and cons of options, more information | Context, facing, decided for, and against, to achieve, accepting that |
| Options and tradeoffs | Implied in the context | Explicit, with pros and cons per option | Named in one clause |
| Metadata | Status only | YAML front matter: status, date, decision-makers, consulted, informed | None |
| Best for | Most teams starting out | Decisions with several real contenders | Small decisions, or a summary at the top of a longer record |
| Tooling | adr-tools generates and links files | Bare and minimal template variants available | None needed |
MADR stands for Markdown Architectural Decision Records. Version 4.0.0 was released in September 2024 and includes “bare” and “minimal” variants alongside the full template. Y-statements were proposed by Olaf Zimmermann in 2012 and follow a single-sentence shape: “In the context of [situation], facing [need], we decided for [option] (and against [alternatives]) to achieve [goals], accepting that [consequences].”
When to write one
Write an ADR when a decision is expensive to reverse, affects more than one team or service, or is likely to be questioned later. AWS’s guidance lists the usual categories: structure (like adopting microservices), non-functional requirements (security, availability), dependencies between components, interfaces and published APIs, and construction techniques (libraries, frameworks, tools, and processes). Vendor choices count, which is why every build vs. buy decision deserves one.
Skip it when the decision is small in scope, cheap to undo, and low risk, or when it’s already documented somewhere else. Not every library upgrade needs a record. If you’re unsure, ask whether a new teammate would be confused by the choice a year from now. If yes, write it down.
Timing matters too. Writing the record while you decide, not after, is where much of the value comes from. Fowler notes that the act of writing helps clarify thinking and brings disagreements to the surface while they can still be discussed.
A copy-paste template
This template combines Nygard’s core sections with the extras that Microsoft and MADR recommend. Delete any section you don’t need.
# NNNN. Short noun phrase describing the decision
- Status: Proposed | Accepted | Rejected | Deprecated | Superseded by [NNNN](NNNN-title.md)
- Date: YYYY-MM-DD
- Deciders: names or roles
- Consulted: names or roles
## Context
What problem are we solving? What forces are at play: requirements,
constraints, deadlines, budget, team skills? State facts neutrally.
## Options considered
1. Option A — one-line summary
2. Option B — one-line summary
3. Option C — one-line summary
## Decision
We will ... because ...
## Consequences
Good:
- ...
Bad, or accepted tradeoffs:
- ...
## Confidence
High | Medium | Low, and why.
## Revisit if
- A specific, observable change that would make us reconsider.
A worked example
Here’s a complete record for a common decision: choosing a transactional email provider. The team, numbers, and requirements are invented for illustration; the vendor details come from each vendor’s public pricing page as of October 2026.
# 0007. Use Postmark for transactional email
- Status: Accepted
- Date: 2026-10-03
- Deciders: Platform lead, CTO
- Consulted: Support lead, Marketing lead
## Context
Our app sends password resets, sign-in links, receipts, and weekly
digests. We send about 8,000 emails a month today and expect roughly
40,000 within a year. Today we send from the app server's SMTP relay;
support tickets show sign-in links landing in spam.
Marketing wants newsletters later, and we don't want promotional mail
to affect delivery of sign-in links.
Two engineers maintain the backend. Neither has run email
infrastructure before.
## Options considered
1. Amazon SES — pay per message, we already use AWS.
2. Postmark — transactional-focused service with separate streams
for transactional and broadcast mail.
3. Self-hosted mail server — full control, no per-message fee.
## Decision
We will use Postmark for all transactional email, with newsletters on
a separate broadcast message stream when marketing needs them.
We chose it over SES because the team values a service focused on
transactional mail, with transactional and broadcast sending kept in
separate message streams, more than the per-message savings. We
rejected self-hosting because neither engineer wants to own
deliverability and IP reputation.
## Consequences
Good:
- Faster setup; we expect to ship in one sprint.
- Transactional and broadcast mail are separated by default.
- A free developer plan (100 emails a month) is enough for staging tests.
Bad, or accepted tradeoffs:
- Higher per-message cost than SES. Postmark Basic is $15/month for
10,000 emails; SES à la carte pricing is $0.10 per 1,000 emails, or
about $1 for the same volume (pricing as of October 2026; new SES
accounts start on a plan with higher rates and can switch).
- One more vendor account, outside our AWS bill.
- Default message retention is 45 days, so we must log delivery
events ourselves if support needs a longer history.
All sending goes through our own `Mailer` interface so a later switch
only touches one module.
## Confidence
Medium. Volume forecasts are rough.
## Revisit if
- Monthly email spend exceeds $150.
- We need sending from a region or account Postmark can't support.
- Marketing volume grows large enough to justify a dedicated tool.
Notice what makes this record useful: a stranger could read it in five minutes and understand both what was decided and what would justify changing it. The tradeoffs are stated, not hidden. And it’s honest about confidence.
Which approach for your team
Solo founder. Keep it tiny. A Y-statement or a half-page Nygard record in a docs/decisions folder is enough. The future reader is mostly you, after you’ve forgotten.
Growing startup. Adopt one template and use it consistently. Add ADRs to your pull request checklist for changes that touch infrastructure, vendors, or public APIs. New hires can read the decision log as onboarding.
Larger or regulated organization. Add review. AWS describes a lightweight process: the record’s owner opens it as Proposed, the team spends 10 to 15 minutes reading it at the start of a review meeting, comments are discussed, and the record moves to Accepted or Rejected. Code reviewers can then link to ADRs when a change conflicts with an accepted decision. For decisions that span many repositories, Fowler notes that a shared location outside any single repo can make sense.
Where to store them
In the repository, as Markdown, next to the code they describe. That way records are reviewed in pull requests, versioned with the code, and found by anyone who clones the project.
Conventions differ slightly: Nygard suggested doc/arch/adr-NNN.md, Fowler and adr-tools use doc/adr, and MADR recommends docs/decisions with files named like 0007-use-postmark-for-transactional-email.md. Pick one and stick with it. Number records sequentially and never reuse a number. Descriptive file names make the directory listing readable on its own.
If you like a command-line helper, adr-tools can create the directory (adr init), generate a new numbered record (adr new), and create one that supersedes an earlier record (adr new -s 7), updating both files’ status links.
Mistakes to avoid
- Editing accepted records. Fowler, Microsoft, and AWS all agree: once accepted, a record doesn’t change. Write a new one that supersedes it and link the two. The history is the point.
- Writing them after the fact, from memory. You’ll lose the rejected options and the real reasons. Write while deciding.
- Turning them into design docs. Microsoft’s guidance warns against this. Keep the decision clear and standalone, and link to longer design material separately.
- Leaving out the downsides. A record with only benefits reads like a sales pitch, and readers stop trusting the log.
- Writing one for everything. If the log fills with trivia, nobody reads the important entries.
- Hiding them in a wiki nobody opens. Records that live away from the code tend to be forgotten.
Keeping them useful
A decision log is only valuable if people read it. Link to the relevant ADR from code comments, README files, and pull requests where a choice might surprise someone. Put the most important point first; Fowler recommends an “inverted pyramid” style. When a revisit trigger fires, write the superseding record promptly, and update the old one’s status to point to it. Some teams also review open low-confidence decisions once or twice a year, which is a natural moment to retire records that no longer apply.
A quick checklist
- Pick one format (Nygard, MADR, or Y-statements) and one folder.
- Number records sequentially; use descriptive file names.
- Write the record while deciding, not afterward.
- Include context, options considered, decision, consequences, and status.
- State your confidence and the triggers for revisiting.
- Review records in pull requests like code.
- Never edit an accepted record; supersede it and link both ways.
- Link to records from the code and docs where the decision shows up.
Sources
- Documenting Architecture Decisions — Michael Nygard, Cognitect
- Architecture Decision Record — Martin Fowler
- Architectural Decision Records — adr.github.io
- MADR: Markdown Architectural Decision Records
- Architectural Decision Record (Y-Form) template — Design Practice Repository
- Maintain an architecture decision record — Microsoft Azure Well-Architected Framework
- ADR process — AWS Prescriptive Guidance
- Architecture decision record templates and examples — Joel Parker Henderson
- adr-tools — Nat Pryce
- Amazon SES pricing
- Postmark pricing