· 6 min read ·

Choosing an ADR Format: The Decision Before the Decision

Source: martinfowler

Most teams that try Architecture Decision Records abandon them within a few months. Not because the concept is wrong. Not because writing things down is a bad idea. The failure usually happens at a mundane level: the template chosen is either too heavy to fill out under pressure, or too light to be useful when someone reads it eighteen months later.

Martin Fowler’s overview of ADRs is a solid introduction to the concept. An ADR is a short document capturing a single decision, its context, and its ramifications. Store them in the source repository. Write them in markdown. Keep them short. Do not modify them when the decision changes; write a new one and link it. The advice is sound. But the practical question of which format to use, and how that choice shapes whether your team builds a sustainable habit, is where the real work happens.

Where ADRs Came From

Michael Nygard introduced the term in a 2011 post titled “Documenting Architecture Decisions.” His original format was deliberately minimal: Status, Context, Decision, Consequences. Four sections, a couple of paragraphs each. The intent was to lower the barrier enough that people would actually write them.

Nygard’s format remains the most widely cited, but it has a gap. It tells you what was decided and what the context was, but it does not require you to document what you considered and rejected. That omission seems minor until you are six months into a codebase wondering why someone did not use the approach you are about to suggest. The answer might be that it was considered and found wanting for a reason specific to your deployment environment, a reason that no longer exists, or a reason that should have disqualified your current suggestion too. Without a record of alternatives, you have no way to know.

The MADR Alternative

The Markdown Architecture Decision Records (MADR) format addresses this gap. MADR adds an explicit section for considered options with pros and cons for each, a rationale section, and optional fields for related decisions and notes. A minimal MADR entry looks like this:

# Use PostgreSQL for the primary data store

Date: 2024-11-15
Status: Accepted

## Context and Problem Statement

The service needs a relational store for order and inventory data.
We need ACID guarantees and support for complex joins.

## Considered Options

* PostgreSQL
* MySQL 8
* SQLite (embedded, for local dev only)

## Decision Outcome

Chosen option: PostgreSQL

### Positive Consequences
* Mature JSONB support for semi-structured product attributes
* Strong tooling for migrations (Flyway, Liquibase)

### Negative Consequences
* Requires a running Postgres instance in dev; Docker Compose handles this

## Pros and Cons of the Options

### MySQL 8
* Good: familiar to most of the team
* Bad: JSONB support is weaker; we use it heavily for product metadata

### SQLite
* Good: zero operational overhead
* Bad: not suitable for concurrent writes from multiple service instances

This is more verbose than Nygard’s format. It is also far more useful to someone encountering the codebase cold. The “why not MySQL” section is where the institutional knowledge lives.

Y-Statements: The Compressed Alternative

At the other end of the spectrum is the Y-statement pattern, which fits an entire decision into a single sentence:

In the context of serving high-volume read traffic for the product catalog,
facing the need to handle 50k requests per second with sub-50ms p99 latency,
we decided to add a Redis caching layer in front of PostgreSQL,
to achieve the latency target without over-provisioning the database,
accepting that cache invalidation adds operational complexity.

Y-statements work well as executive summaries prepended to longer ADRs. They also work for decisions that genuinely do not need a full document: configuration choices, coding conventions, naming standards. The compressed format forces clarity about the trade-off being accepted, which is the part most people skip.

Tooling

adr-tools is the standard command-line option. It generates sequentially numbered ADR files, provides commands for listing and linking records, and stores everything in doc/adr by default. The tool is shell-based and intentionally simple. Running adr new "Use Kafka for event streaming" creates a numbered file with the Nygard template filled in at the header level. Nothing more.

For teams that want something more searchable, log4brains generates a static site from your ADR directory with full-text search and a timeline view. It supports MADR format and integrates with CI pipelines to deploy the docs site alongside the application. The discoverability improvement is real. A markdown file in doc/adr requires you to know it exists; a searchable web interface means someone can find the Kafka decision by searching for “event streaming” even if they did not know an ADR existed.

What Makes ADRs Fail

The most common failure mode is the accumulation of stale “Proposed” records. A decision is documented before consensus, the discussion happens in a meeting, and the ADR never gets updated to “Accepted.” Over time, the ADR directory fills with proposals in an indeterminate state. Readers cannot tell which decisions are in force.

The fix is procedural rather than technical: treat ADR status updates as part of the code review process. If a pull request implements a decision, the corresponding ADR should move to “Accepted” in the same commit. If it supersedes an earlier decision, both ADRs should be updated. This ties the documentation lifecycle to the development lifecycle rather than leaving it as a separate task that gets deferred indefinitely.

A second failure mode is scope creep in both directions. Teams document minor decisions that do not warrant an ADR, creating noise that makes the valuable records harder to find. Or they document only the biggest decisions and miss the mid-level choices, like which HTTP client library to use, or how to handle retries, that turn out to matter significantly when someone else joins and needs to understand the conventions.

A useful heuristic: if the decision would cause meaningful rework to reverse in three months, it probably warrants an ADR. If reversing it is a one-hour refactor, it probably does not.

The Connection to Larger Documentation Ecosystems

ADRs sit at an interesting intersection with related practices. Rust uses a formal RFC process for language features; Python uses PEPs. Both are longer and more formal than ADRs, oriented toward public consensus rather than internal record-keeping. ADRs borrow the core idea, stripped of the community process overhead, for use within a single team or organization.

The relationship to RFCs matters because it clarifies what ADRs are not designed to do. They do not produce public standards. They do not require external review. Their purpose is to create a written record of reasoning that would otherwise exist only in the heads of whoever was in the room when the decision was made. That constraint, who was in the room, is what makes the format useful and what makes neglecting it expensive.

Teams with high turnover feel this cost most acutely. When the engineers who made the original decisions have left, the ADRs are the only place the reasoning survives. Without them, the next team inherits a set of constraints with no explanation, which produces two bad outcomes: they spend time rediscovering why certain approaches were rejected, or they change things that should not be changed because they never learned the reason they were set up the way they were.

Keeping the Habit

The teams that maintain ADRs successfully tend to treat them the way they treat tests: not as extra work attached to development, but as part of the definition of done for significant decisions. The review checklist includes a question about whether the change implements or supersedes an existing architectural decision. If it does, the ADR is updated or created in the same pull request.

Format matters less than consistency. A team that uses Nygard’s minimal format and fills it out reliably will accumulate more usable institutional knowledge than a team that adopts MADR but rarely completes the alternatives section. The goal is a record that tells the next engineer why, not just what. Any format that reliably produces that outcome is the right format for your team.

Starting with MADR is a reasonable default for most teams. It is well-documented, has good tooling support, and the structured alternatives section is the part that consistently proves its value over time. The official MADR repository provides templates for both minimal and detailed formats, which gives teams a natural progression as they get comfortable with the practice.

Was this interesting?