Architecture Patterns in Production

ADRs That Teams Actually Maintain

A lightweight ADR and RFC template that survives past the first sprint — with the failure modes that kill most decision logs.

Article 6 of 710 minIntermediate
Architecture Patterns in Production
Key Takeaway

An ADR captures why a decision was made, not just what was decided. Most decision logs die because nobody revisits them when the context changes — so they become authoritative lies. A review date and a named owner are the two additions that turn a write-once artifact into a living record. The template below is the whole thing; take it and use it.


What an ADR Is

An Architecture Decision Record documents a significant architectural choice with its context, the decision made, alternatives considered, and the consequences expected. It is a log entry, not a specification. It captures reasoning, not just outcome.

That last sentence is the one worth reading twice. The code tells you what the system does. The ADR tells you why it does it that way instead of the other obvious thing you'd reach for. Without the why, every engineer who joins the team is left guessing — or, worse, makes the same tradeoffs all over again from scratch.

Why Most Decision Logs Die

The standard ADR workflow goes like this: a decision gets made, someone writes it up, it gets committed to /docs/adr/, and it is never opened again.

This is not laziness. It is a structural failure. The ADR described what was true the day it was written. The constraint that drove the decision has changed. The tool comparison is now 18 months stale. The team members who held the context have left.

Consider a real pattern: the ADR says "we chose Redis because our team knows it." That was written when five engineers had deep Redis experience. The team has turned over. Two of the three engineers now on the service have never run Redis in production and actively prefer Valkey, which is compatible and better maintained under their organization's OSS licensing policy. The ADR is still there. It still says Redis. It still reads as authoritative.

The ADR is a lie that looks like documentation.

The root cause is not that people wrote bad ADRs. It is that the ADR has no mechanism to surface that its context has expired. A decision log without a review date is a time capsule. The question is whether you intend it to be.

The Lightweight Template (Paste-Ready)

Use this. Do not design a better one. The overhead of the template is the biggest adoption killer — if it takes more than 15 minutes to write, it will not get written.

# ADR-[number]: [Title]
Date: YYYY-MM-DD
Status: [Proposed | Accepted | Deprecated | Superseded by ADR-N]

## Context
What is the situation or problem that forced this decision? What constraints
apply (team size, timeline, existing systems, budget)?

## Decision
What did we decide? State it as a directive, not a hedge.

## Alternatives Considered
| Option | Why Rejected |
|--------|--------------|
| Option A | Reason |
| Option B | Reason |

## Consequences
**Positive:** What gets better?
**Negative:** What gets worse or harder?
**Risks:** What could go wrong that we're accepting?

## Review Date
[Set to 3–6 months out. Someone is responsible for reviewing this.]

Two non-negotiable fields: the Decision must be a directive ("We will use PostgreSQL for all persistent writes in this service"), not a summary ("We decided to look at PostgreSQL"). And the Review Date must name a specific date and a specific owner — not "eventually" and not "the team."

ADR vs RFC: When to Debate in the Open, When to Just Decide

Both documents capture architectural reasoning. They are not interchangeable.

An RFC — Request for Comments — is for decisions that affect multiple teams, require input to be complete, or will generate enough disagreement that you need evidence of the deliberation. An RFC is a conversation artifact. The outcome of that conversation is then captured in an ADR.

An ADR is for decisions your team owns entirely. If you are the only team that touches this service and the decision does not change the contract between your service and any other, write an ADR directly.

The rule of thumb: if the decision affects only your service, write an ADR. If it affects the contract between services — the API shape, the event schema, the data ownership boundary — write an RFC first, then an ADR when the decision is made.

The failure mode to avoid: writing an RFC for a decision that only your team needs to make, because it feels more legitimate. RFCs generate comments. Comments generate meetings. You wanted legitimacy; you got a month of process for a decision that should have taken an afternoon.

The Review Date Is the Mechanism

The review date is not a suggestion. It is the single mechanism that keeps ADRs from becoming write-once artifacts.

When the date arrives, the conversation is short: "Is this decision still right?" That is a 10-minute question, not a committee. The review produces one of three outcomes.

First: the decision holds. The context has not changed materially, the consequences are as expected, and the team still agrees with the choice. Status stays Accepted.

Second: the context has changed but the decision is still right. Update the Context section. Reset the review date.

Third: the decision has already been superseded — possibly without anyone noticing. Someone made a different choice without documenting it. This is the most common outcome. Now you write a new ADR and mark the old one as Superseded. The new ADR captures what actually happened and why.

Without the review date, you never surface outcome three. The old ADR stays Accepted. The codebase drifts. The documentation diverges from the system. New engineers trust the document and the document is wrong.

Name an owner for the review. Not the team. A person. The person who wrote the ADR is the default if no one else is assigned.

What to Write an ADR For (and What Not To)

The right heuristic: write an ADR for any decision you would have to explain to a new architect joining the team six months from now.

Examples that warrant an ADR:

  • "Why do we use PostgreSQL instead of MongoDB for this service, given that all our other services use Mongo?"
  • "Why is this service synchronous when the rest of the system is event-driven?"
  • "Why is the payments module a monolith when everything else is decomposed?"
  • "Why are we running two message brokers instead of standardizing on one?"

Examples that do not warrant an ADR:

  • How a specific function is implemented (use a code comment)
  • The choice of a library version (use a CHANGELOG or PR description)
  • A temporary workaround with a ticket tracking the cleanup (use the ticket)

The signal is: would a capable engineer question this decision on first read, and would the answer require context that is not obvious from the code? If yes, write the ADR.

Do not write ADRs for every decision. The overhead of the record is the cost you pay. Reserve it for choices that, if reversed, would require meaningful work — or choices that, if undocumented, will be reversed accidentally.

ADR Lifecycle

The lifecycle has one non-obvious property: most ADRs should eventually reach Superseded or Deprecated. If your decision log has 40 ADRs and none of them have been deprecated in three years, either your architecture has not changed or your review dates are not being honored. Neither of those is a healthy sign.

Going Deeper

The template above is enough to start. Once your team has shipped a few ADRs and the review cadence feels natural, the harder question becomes curation: what is in your decision log, how is it indexed, and how does a new engineer navigate it without reading 40 documents?

For the deeper treatment — including how to organize ADR numbering, handle cross-team ADRs, and integrate the process into your RFC workflow — the architecture decision records that people actually maintain post on the blog covers the organizational layer this walkthrough deliberately skips.