Start Learning
Javaneer
Back to stage
Stage 6·Evolutionary Architecture

Architecture Decision Records

Give the architecture a memory: a lightweight ADR captures a decision, its context, and its consequences - so future engineers evolve the system knowing why it is the way it is.

12 min readIntermediate
On this page

A system that evolves for years faces a quiet, corrosive problem: it forgets why it is the way it is. A new engineer sees an odd choice - "why do we use two databases here?" - and either wastes days rediscovering the reason or, worse, "fixes" it and reintroduces the exact bug it was avoiding. Architecture Decision Records (ADRs) give the architecture a memory: a lightweight, durable record of each significant decision, its context, and its consequences. It's the last piece of evolutionary architecture - because you can't evolve well what you don't understand.

The problem: institutional amnesia

Architectural decisions are made in meetings, Slack threads, and someone's head - and then that context evaporates. People leave, memories fade, and six months later nobody can say why a choice was made. The result:

  • Repeated debates - the same decision re-litigated because no one remembers it was settled, and why.
  • Cargo-culting - a pattern copied without understanding, applied where it doesn't fit.
  • Accidental reversal - someone undoes a decision, not realizing it was deliberate, and resurrects the problem it solved.

Comments in code capture how; they rarely capture why this over the alternatives. That "why" is exactly what gets lost, and it's the most expensive thing to reconstruct.

What an ADR is

An ADR (popularized by Michael Nygard) is a short markdown file - a page or less - recording one significant architectural decision. Kept in the repo alongside the code (e.g. docs/adr/0007-use-outbox-for-events.md), it's version-controlled, reviewable in a PR, and lives where engineers work. A common template:

# 7. Use the transactional outbox for cross-service events

## Status
Accepted   (others: Proposed | Deprecated | Superseded by ADR-12)

## Context
We publish events across service boundaries. Publishing after the DB commit
risks losing events if the app crashes between commit and publish. We need
reliable delivery without a distributed transaction.

## Decision
Persist each event in the same transaction as the state change (an outbox
table), and publish it asynchronously from there.

## Consequences
+ Events are never lost; at-least-once delivery.
+ No distributed transaction needed.
- Consumers must be idempotent (duplicates possible).
- An outbox table and a relay process to maintain.

The four sections are the whole point: Status (is it current?), Context (the forces and constraints - why this came up), Decision (what we chose), Consequences (the trade-offs, good and bad, we accepted).

Why the "why" is the treasure

The most valuable section is Context, because it captures the forces at the time - the constraints, alternatives considered, and trade-offs. A future engineer reading it understands not just what was decided but why it made sense then, which lets them judge whether it still makes sense now:

  • If the forces are unchanged, they respect the decision instead of relitigating it.
  • If the forces have changed (you've since adopted a message broker with transactional guarantees), they can consciously supersede the ADR - writing a new one that references the old - rather than blindly reversing it.

This is what makes ADRs an evolutionary tool: decisions aren't frozen, they're remembered and revisited with full context. An ADR is never deleted; when superseded, its status changes and it points to its replacement, so the history of the architecture's reasoning is preserved.

Record decisions when they're made, and only the significant ones

Write the ADR at the moment of the decision, while the context is fresh - reconstructing it months later loses exactly the reasoning you're trying to capture. And record only architecturally SIGNIFICANT decisions: choices that are costly to reverse, affect multiple teams, or that a newcomer would question ('why this database?', 'why this boundary?'). Not every library choice needs an ADR - that just creates noise. A handful of well-written ADRs about the load-bearing decisions is worth more than hundreds of trivial ones.

A ship's logbook across many captains

A long-lived system is a ship that outlasts its crew - captains come and go over decades. Without a logbook, each new captain inherits a vessel full of unexplained modifications: a reinforced hull here, an unusual rigging there, and no idea whether they're vital or vestigial. They might 'simplify' the reinforced hull - and sink in the first storm it was built to survive. An ADR is a logbook entry: 'Reinforced the hull on the north route (Context: recurring ice damage); accepted heavier, slower ship (Consequences).' A future captain reading it understands the reasoning, keeps the reinforcement while the ice route remains - or, if the route changed, deliberately removes it and logs that decision. The ship's accumulated wisdom survives its crew, so each generation evolves it knowingly rather than blindly.

When and what to record

A team makes several decisions in a sprint: (a) they choose an unusual pattern of splitting one entity across two databases for a specific consistency reason; (b) they pick the Jackson library over Gson for JSON; (c) they decide to keep the payments module as a modular-monolith module rather than extract it to a service, for now. Which warrant ADRs and why, and for one of them, what's the single most important thing to capture?

What is the most valuable thing an Architecture Decision Record captures, and why?

Key takeaways

  • Long-lived systems suffer institutional amnesia - the 'why' behind decisions evaporates, causing repeated debates, cargo-culting, and accidental reversals.
  • An ADR is a short, version-controlled markdown file recording one significant decision: its Status, Context, Decision, and Consequences.
  • Kept in the repo alongside code, ADRs are reviewable in PRs and live where engineers work; the Context (the 'why') is the most valuable part.
  • ADRs make architecture evolvable: decisions are remembered and can be consciously superseded (status changed, pointing to a replacement) when forces change - never blindly reversed.
  • Write ADRs when decisions are made, while context is fresh, and only for architecturally significant, costly-to-reverse choices - not routine library picks.
Was this lesson helpful?
Edit this page on GitHub