An architecture decision record is valuable only while it helps someone make or revisit a decision. A folder full of polished documents can still fail that test: one record reports that a queue was selected but not why, another describes an option that was never implemented, and a third remains marked “accepted” years after its assumptions stopped being true. The files preserve text while the reasoning disappears.
The useful model is not “write down every architecture discussion.” It is maintain a small, versioned interface between a consequential decision and the system it governs. The record names the context, the options considered, the chosen direction, the consequences the team accepts, and the evidence that should cause another review. Its lifecycle follows the decision rather than ending when a pull request merges.
This framing keeps ADRs lightweight without making them disposable. It also makes them operational: code reviewers can check a change against a decision, operators can connect an incident to an assumption, and a future team can supersede a choice without reconstructing history from chat messages.
Record Decisions, Not General Knowledge
An ADR should answer a question for which multiple plausible choices have materially different consequences. “Use PostgreSQL 17” may be a decision if it chooses the persistence boundary for a new product and rejects credible alternatives. “PostgreSQL supports transactions” is background knowledge and belongs in documentation only if readers need it.
A practical threshold is to record a choice when at least one of these is true:
- It establishes a constraint that several modules or teams must follow.
- Reversing it would require migration, coordination, or customer-visible change.
- Reasonable engineers could choose differently because the tradeoffs are not obvious.
- It accepts a meaningful risk, operational burden, or limitation.
- A future change is likely to look locally attractive while violating a system-level invariant.
The record is not a meeting transcript. Participants, exploratory ideas, and a chronological debate rarely help a future reader. Distill the decision at the point where its forces are understood well enough to compare options. Small implementation choices remain in code and review history; broad principles belong in an architecture guide. ADRs occupy the middle: discrete choices with durable consequences.
Scope must be explicit. “All services use asynchronous communication” is too broad to verify and likely wrong. “Customer export generation is asynchronous after request validation; status reads remain synchronous” identifies the capability and boundary. A scoped decision can later be superseded without pretending the entire platform changed at once.
Note
An ADR records authority, not certainty. It says which option was chosen under named assumptions. It does not claim that the option is universally best or permanently correct.
Make Context Falsifiable
Weak context says, “We need a scalable solution.” Strong context describes the pressure that makes a decision necessary and the constraints that eliminate otherwise sensible choices. Readers should be able to tell whether those conditions still hold.
Useful context separates five things:
| Element | Question it answers | Example |
|---|---|---|
| Problem | What must change or become possible? | Export requests exceed the synchronous request deadline. |
| Scope | Which capability and interfaces are governed? | Generation and delivery of customer account exports. |
| Forces | Which qualities compete? | Recovery, implementation effort, auditability, and portability. |
| Constraints | What cannot this decision change? | The existing relational database remains the system of record. |
| Assumptions | Which believed facts could later become false? | Export volume fits the current worker fleet with bounded concurrency. |
Avoid unsupported precision. If no measurement exists, do not invent one to make the ADR look empirical. State the observable condition instead: “Some exports exceed the gateway deadline” can be established from traces, while an illustrative target should be labeled as a proposed requirement. Link evidence when it is stable and access-controlled, but summarize the relevant fact so the decision remains intelligible if a dashboard or ticket disappears.
Decision criteria should be ordered, not merely listed. If recoverability matters more than minimum dependency count, say so before comparing options. Otherwise every option can be made to win by emphasizing its favorite dimension. Hard constraints, such as data residency or compatibility, should be distinguished from preferences that can be traded.
Context also identifies non-goals. A decision about export execution need not redesign authentication, storage retention, or the public API unless those are genuinely coupled. Non-goals keep a record from becoming an architecture proposal for the entire system.
Compare Real Options and Consequences
Every accepted ADR needs at least one credible alternative. “Do nothing” is often credible, especially when migration cost may exceed the benefit. A straw option such as “rewrite everything” does not demonstrate reasoning.
Compare options against the same criteria. A compact table is often enough:
| Option | Recovery | Operational surface | Portability | Main risk |
|---|---|---|---|---|
| Extend synchronous processing | Request retry only | Low | High | Work is lost or repeated after disconnects. |
| Database-backed job state | Durable local recovery | Moderate | High | Polling and worker ownership must be designed. |
| Managed workflow service | Durable workflow primitives | Higher | Lower | Product semantics become coupled to a vendor model. |
The decision section should be short and normative: who will do what, at which boundary, and from when. The explanation belongs in rationale. This distinction lets reviewers quote the rule without extracting it from several paragraphs.
Consequences are commitments, not ceremonial pros and cons. Positive consequences explain the value being purchased. Negative consequences name the cost the team agrees to carry. Neutral consequences describe follow-on work or constraints. “Workers must expose queue age and retry state” is more useful than “additional complexity.” Assign an owner or follow-up issue when a consequence requires action, but do not turn the ADR itself into a project tracker.
Rejected options should retain their strongest case and the reason they lost under current forces. This makes a future reversal legitimate. If the dominant force changes, the rejected option may become correct; an honest record lets a new review start from that fact rather than defending the old choice as doctrine.
Work an ADR from Proposal to Acceptance
Consider an illustrative product that generates account exports. Generation sometimes outlives an HTTP request, and clients retry when connections close. The team must decide how to own durable execution.
# ADR-0042: Persist account-export work in the application database
Status: Proposed
Owners: Accounts and Platform
Decision date: Pending
Context:
Account-export generation can outlive the request that starts it. A lost
response causes clients to retry, so execution needs a durable identity and
recoverable state. The application database is already operated in every
deployment. The current scope does not require general workflow authoring.
Criteria, in order: prevent duplicate exports, recover after worker restart,
preserve deployment portability, then minimize new operations.
Options:
1. Keep generation inside the request.
2. Store export jobs and leases in the application database.
3. Adopt a managed workflow service.
Decision:
Store one export job per idempotency key in the application database. Workers
claim bounded batches with expiring leases. Object storage holds completed
artifacts; the job row holds state, attempt history, and the artifact key.
Consequences:
- Request handlers return after durable job creation, not export completion.
- Workers require lease recovery, bounded retries, and queue-age telemetry.
- The schema is application-owned and must be migrated compatibly.
- A workflow service remains an option if branching or long waits become a
dominant requirement.
Review triggers:
- Export workflows gain human approvals or multi-day waits.
- Database polling interferes with foreground traffic.
- More than one product needs the same workflow primitives.
During proposal review, the security owner adds that artifact authorization is checked at download time; the database owner confirms that claim queries use an indexed status and due-time key. A short prototype demonstrates lease recovery after a worker exits. These findings update context and consequences before acceptance.
When the pull request implementing job creation and claiming merges, the ADR status changes to Accepted, its decision date is filled, and the code links back to ADR-0042 at the module boundary. If implementation instead reveals that the database cannot satisfy a hard constraint, the proposal becomes Rejected with the finding recorded. Rejection is useful history; deleting the file would invite the same failed option later.
The worked record does not specify every retry interval, column, or endpoint. Those belong in code and operational documentation. It establishes ownership and invariants: durable creation precedes acknowledgment, one idempotency key identifies one export, claims are recoverable, and adoption of a broader workflow platform has named triggers.
Give Records an Honest Lifecycle
Status is a state machine, not decoration. Keep the vocabulary small and define it once for the repository:
Proposed: open for review and not yet authoritative.Accepted: governs the named scope.Rejected: considered but not adopted; rationale remains useful.Superseded: replaced wholly or partly by a newer decision.Deprecated: still describes deployed reality but should not guide new work.
Do not edit an accepted ADR until it appears that the old decision was always different. Correct spelling and broken links freely, and append clarifications that do not change meaning. A material change gets a new ADR that links to and supersedes the old one. Immutable reasoning plus explicit supersession preserves both chronology and current authority.
Partial supersession needs precision. A new record might replace the worker-claiming mechanism while retaining database-backed job identity. State which clauses changed, and update the old record’s status header or metadata with a link. Readers should not have to infer precedence from file dates.
Some teams add Amended, but amendments can become a loophole for silently rewriting policy. Prefer a new decision whenever criteria, owner, scope, or consequences materially change. The cost of one small file is lower than the cost of ambiguous history.
Retirement matters too. When the last governed implementation disappears, mark the ADR deprecated or superseded and link the removal change. An accepted decision with no remaining subject creates false constraints for future work.
Put ADRs in the Repository Workflow
Store ADRs near the code or configuration they govern, in a location with clear ownership. Repository placement makes review, history, and branch coordination ordinary engineering work. It also permits checks that external document systems often make difficult.
Use stable identifiers independent of titles, such as 0042-account-export-execution.md. Titles change as wording improves; links should not. Choose a numbering policy that tolerates parallel branches. A central sequence is readable but can collide, while a timestamp or generated identifier reduces coordination. The particular scheme matters less than stability and automation.
An ADR pull request should include the affected owners and, when appropriate, implementation changes. Proposal-first review is useful when code would be expensive to reverse. For a small decision, record and implementation can share one pull request, provided acceptance means the implementation actually follows the record. Avoid accepting a speculative future architecture with no owner or delivery path.
Create a lightweight index with ID, title, status, owners, scope keywords, and superseding record. Generate it from machine-readable frontmatter if the repository already uses structured tooling; otherwise maintain a simple table. Searchability should not require a custom portal.
Links form a decision graph:
- Code and configuration link to the ADR that explains a surprising constraint.
- A new ADR links to records it supersedes or depends on.
- Runbooks link to decisions that establish degraded behavior.
- ADRs link to stable specifications or evidence, while summarizing the relevant fact.
Ownership must survive team renames. Prefer a repository ownership group or capability name backed by CODEOWNERS, not only an individual’s name. The owner is accountable for review triggers and current status, not necessarily the original author.
Use Triggers Instead of Ritual Reviews
Calendar review can find stale records, but “review annually” rarely identifies what to evaluate. A strong ADR declares conditions that challenge its reasoning. Triggers derive directly from assumptions, constraints, and accepted consequences.
Types of trigger include:
- Scale: a queue, data set, tenant count, or dependency shape crosses a designed boundary.
- Capability: the workflow gains branching, approval, portability, or consistency requirements the option did not address.
- Failure: an incident demonstrates that a named recovery assumption is false.
- Economics: an accepted operational cost becomes material relative to an alternative.
- Platform: a required technology reaches end of support or a constraint disappears.
- Organization: ownership divides so the original coordination model no longer fits.
A trigger should lead to a review, not predetermine reversal. “Database polling causes observable contention with foreground requests” asks the owners to compare options using new evidence. It does not automatically mandate a workflow service.
Make triggers observable where proportionate. A consequence that requires queue-age telemetry can point to an alert or service-level objective. A dependency lifecycle trigger can be checked from a version manifest. Not every architectural premise can be automated, but each should have a plausible source of evidence.
Test the Decision System and Avoid Failure Modes
ADRs need verification at two levels. First, verify document integrity: required fields exist, identifiers and links are unique, accepted records have owners and dates, and superseded records point to valid successors. A small lint script can catch mechanical decay without judging architecture.
Second, verify conformance where a decision expresses enforceable boundaries. Dependency rules can be architecture tests; required encryption can be configuration policy; API compatibility can be contract tests. Do not force every consequence into a brittle static rule. Operational practices such as incident ownership may be better checked through runbooks and exercises.
Review a sample through practical questions:
- Can a reader state the decision without reading its rationale twice?
- Do the context and criteria explain why the selected option won?
- Are costs and failure modes explicit rather than hidden as “complexity”?
- Does status match deployed reality?
- Can owners tell which evidence would prompt reconsideration?
- Can affected code, runbooks, and successor records find this ADR?
Common failure modes are predictable. Recording everything makes the collection noisy. Recording only successes erases learning. Treating accepted records as immutable commandments prevents evolution, while rewriting them destroys history. A separate architecture board can become a bottleneck if it owns decisions without owning consequences. Templates can encourage completeness, but a long mandatory form produces filler.
The tradeoff is maintenance. A useful ADR practice costs review attention and occasional cleanup. Keep that cost proportional: record consequential choices, use a compact template, automate mechanics, and assign lifecycle ownership. Measure usefulness through stale-status findings, broken links, repeated debates, and whether incident or design reviews can locate governing decisions, not through the number of documents created.
Architecture decision records stay useful when they preserve a live chain from forces to choice to consequences to evidence. The file is only the container. The real asset is a decision that remains discoverable, challengeable, and honest about the conditions under which it should change.