ADR Template and Examples: Copy-Ready Formats
The meeting had been going for two hours. We were debating whether to use PostgreSQL or MongoDB for a new service. Arguments flew back and forth: relational integrity, flexible schemas, team familiarity, operational complexity.
Then someone mentioned: "Didn't we have this exact discussion last year for the user service?"
Silence. We had. A year earlier we'd spent just as long on the same question and chosen PostgreSQL. Nobody remembered the reasoning, and the engineer who led that discussion had left the company. So we were having the same debate from scratch.
That's when we started writing Architecture Decision Records. This post is the copy-paste part: three templates, when to use each, and three of our own decisions filled in.
What's an ADR?
An architecture decision record is a short document that captures a single architectural decision. Not a design document covering everything about a system, just one decision:
- What we decided
- Why we decided it
- What alternatives we considered
- What the consequences are
An ADR should fit on a page or two. If it's longer, you're probably documenting more than one decision. The complete guide covers when to write one, the lifecycle, and the mistakes teams make; this post sticks to the formats.
The Minimal Template (Nygard)
Michael Nygard proposed the format most teams still use in a 2011 post. Five parts: a title that's a short noun phrase, a status, the context ("the forces at play"), the decision ("our response to these forces"), and the consequences ("the resulting context, after applying the decision"). His statuses are Proposed, Accepted, Deprecated and Superseded.
# ADR-NNNN: Short noun phrase
## Status
Proposed | Accepted | Deprecated | Superseded by ADR-XXXX
## Context
What forces are at play? Technical, organisational, deadline, budget.
Be specific: numbers, constraints, who is affected.
## Decision
We will ...
## Consequences
What becomes easier, what becomes harder, what we now have to watch.
We add one section to it: Alternatives Considered, between Decision and Consequences. It's the part that saves the most time later, because the question you get a year on is rarely "what did we pick?" and almost always "why didn't we pick X?"
## Alternatives Considered
### Option B
- Pros: ...
- Cons: ...
- Why rejected: ...
MADR
MADR (Markdown Architectural Decision Records) is a more structured template maintained at adr.github.io/madr. The current version is 4.0.0, released on 17 September 2024. It puts metadata in YAML frontmatter and makes the options and their trade-offs explicit sections rather than prose.
---
status: proposed | rejected | accepted | deprecated | superseded by ADR-XXXX
date: YYYY-MM-DD
decision-makers: ...
consulted: ...
informed: ...
---
# Short title of the problem solved and the solution chosen
## Context and Problem Statement
Two or three sentences, or a short story. Ideally phrased as a question.
## Decision Drivers
* Driver 1
* Driver 2
## Considered Options
* Option A
* Option B
* Option C
## Decision Outcome
Chosen option: "Option A", because ...
### Consequences
* Good, because ...
* Bad, because ...
### Confirmation
How we will check the decision is implemented (review, test, fitness function).
## Pros and Cons of the Options
### Option A
* Good, because ...
* Bad, because ...
## More Information
Links, related decisions, when to revisit.
Every section after Considered Options and Decision Outcome is optional in MADR. Delete what you don't use rather than leaving empty headings.
Y-Statement
The Y-statement fits a decision into one sentence. It comes from Uwe Zdun, Olaf Zimmermann and colleagues ("Sustainable Architectural Design Decisions", IEEE Software, 2013):
In the context of <use case or component>,
facing <concern or requirement>,
we decided for <option>
(and against <other options>),
to achieve <quality or benefit>,
accepting that <downside>.
It's too short to carry a full context section, and that's the point. Use it for decisions that don't deserve a page, as the summary line at the top of a longer ADR, or as the entry format in a decision log.
Which Format to Use
| Format | Use it when | Watch out for |
|---|---|---|
| Nygard (plus alternatives) | You're starting out, or most decisions have one obvious winner and a couple of rejected options | Context sections that grow into essays |
| MADR | Decisions are contested, several people need to sign off, or you want options and drivers comparable across ADRs | Filling in every optional section out of habit |
| Y-statement | Small decisions, a decision log, or a one-line summary on top of a longer ADR | Using it for decisions that need a real context section |
Pick one for the repository and stick to it. Mixed formats are harder to scan than any single format is to write.
Example 1: ADR-0042, PostgreSQL for the Order Service
This is the decision from the opening story, in the Nygard format with our Alternatives Considered section.
# ADR-0042: Use PostgreSQL for Order Service
## Status
Accepted
## Context
The order service needs persistent storage for order data. We expect
to process 50,000 orders per day initially, growing to 500,000 within
two years. Orders have a well-defined structure but may need additional
metadata fields over time. The team has experience with both relational
and document databases.
## Decision
We will use PostgreSQL 15 as the primary database for the order service.
We chose PostgreSQL because:
- ACID compliance is required for financial order data
- JSON columns provide schema flexibility for metadata
- Our infrastructure team has operational experience with PostgreSQL
- Query patterns are well-suited to relational modeling
## Alternatives Considered
### MongoDB
- Pros: native JSON storage, simpler horizontal scaling, flexible schema evolution
- Cons: weaker consistency guarantees, team less familiar with operations,
would require additional tooling for transactions
### DynamoDB
- Pros: fully managed, minimal operations, excellent scalability
- Cons: vendor lock-in to AWS, query patterns limited to partition/sort
key access, cost unpredictable at high scale
## Consequences
### Positive
- Strong data integrity guarantees
- Team can reuse existing PostgreSQL expertise
- Well-understood operational characteristics
### Negative
- Schema migrations require more planning than document stores
- Horizontal scaling more complex if we exceed single-node capacity
- Need application-level sharding if we hit scale limits
### Risks
- May need to revisit if order volume exceeds 1M/day
- JSON column queries less efficient than native document stores
## Related Decisions
- See ADR-0007 for why we accept eventual consistency
- Supersedes ADR-0003, which recommended MongoDB
Be specific in the context. "We need ACID compliance" helps the next reader far more than "we need reliability". And be honest in the consequences: no decision is free, and writing down the downsides tells future teams when it's time to revisit.
Example 2: ADR-0007, Event-Driven Communication, in MADR
The Kafka decision had more options on the table and more people involved, which is where MADR's explicit drivers and options earn their space.
---
status: accepted
---
# Use Kafka for asynchronous communication between services
## Context and Problem Statement
Our microservices communicate synchronously over HTTP. That couples them
tightly, and an unavailable service cascades into failures upstream.
How should services communicate when the caller doesn't need an
immediate answer?
## Decision Drivers
* Resilience: one service being down must not take others with it
* Looser coupling between services
## Considered Options
* Keep synchronous HTTP
* Event-driven communication with Apache Kafka
## Decision Outcome
Chosen option: "Event-driven communication with Apache Kafka", because it
removes the runtime coupling that causes cascade failures.
### Consequences
* Good, because services become more resilient to each other's failures
* Bad, because we move from strong to eventual consistency
* Bad, because we now operate a Kafka cluster
* Bad, because the team needs training on event-driven patterns
The status and title carry over; the date and decision-makers fields are left out here because the original record didn't keep them.
Example 3: ADR-0015, a Frontend Monorepo, as a Y-Statement
The monorepo decision fits in one sentence, and the sentence is enough to answer "why is everything in one repo?"
In the context of our 5 frontend applications in separate repositories,
facing version mismatches and the overhead of publishing packages to share code,
we decided for a single monorepo managed with Nx
(and against separate repos with better package management, and against a monorepo without Nx),
to achieve simple code sharing and one pull request that updates shared code and all its consumers,
accepting that a larger repository needs build caching and that applications can become coupled by accident.
The rejected options carry their reasons in the full record: separate repos kept the coordination overhead, and a monorepo without Nx would have made build times prohibitive.
Where to Keep Them
Put ADRs in the repository they describe, in docs/adr/ or docs/decisions/ (Nygard suggested doc/arch/adr-NNN.md). They're versioned with the code, they show up in code review, and they can't get lost in a wiki.
Number them sequentially and never reuse a number. When a decision changes, write a new ADR that supersedes the old one and update the old one's status, rather than editing history.
The step most teams skip is connecting an ADR to the part of the system it affects. In Archyl, an ADR carries Nygard's fields (status, context, decision, consequences) plus a date and a superseded-by link, and attaches to the systems, containers and components it shaped. Anyone looking at the order service in the C4 diagram sees ADR-0042 next to it: "Why is this service on PostgreSQL?" is one click away.
The pitfalls (writing ADRs after the fact, letting them run to five pages, abandoning the practice after the first busy quarter) are covered in the complete guide.
Start With One
That two-hour meeting about PostgreSQL vs MongoDB? The next time the question came up, it ended in ten minutes, because someone found ADR-0042. The constraints, the alternatives and the reasoning were all there. We confirmed the original decision still applied and moved on.
Pick one of the templates above and paste it into docs/adr/0001-record-architecture-decisions.md. Your first ADR can be the decision to write ADRs.
Learn more about architecture documentation: the C4 model guide | Why Documentation Matters | Documenting User Flows