That person left the company. The code is still there, but nobody can explain why it was designed that way. Everyone in the conference room looks at each other blankly. The final conclusion: "let's not touch it." This isn't a management problem or a capability problem — it's a recording problem.

Almost every engineer has lived this scenario. The issue is never "we thought wrong back then" — it's "the context from back then can't be recovered." The decision-maker might still be around, but they can't remember why, three months ago, they chose this option over another that looked about the same.

That's what ADRs solve.

An ADR is a Markdown file, usually under one page. It records only five things:

  • Title: a heading suffices
  • Status: current state — proposed or accepted, etc.
  • Context: what problem was faced, what constraints existed
  • Decision: what decision was made, and why
  • Consequences: after choosing — what's good and what's not

No complex templates, no tooling required. A file named ADR-001-use-mysql-as-primary-storage.md represents one architectural decision.

Imagine your team is deciding on primary storage. Context: data volume expected at tens of millions, team is most familiar with MySQL, business requires strong consistency, no complex analytical query needs for now.

Decision: choose MySQL as primary storage.

Consequences must include both positive and negative. Positive: existing team experience, mature transaction support, complete operations tooling. Negative: horizontal scaling requires additional design (sharding, read-write splitting), limited support for complex analytical queries, full-text search at scale requires introducing Elasticsearch.

The point here — don't just write the benefits in Consequences. If an ADR only has "what we chose" and "why," it's just a note with a reason. What's truly valuable is "what costs we accepted after choosing." Six months later when someone complains about slow queries, this ADR directly answers: we knew MySQL wasn't great at analytics when we chose it, and we accepted that cost.


Understanding what an ADR isn't is as important as understanding what it is.

An ADR isn't a design document. Design documents expand implementation details, API definitions, data structure designs. An ADR only records decisions and reasons, not implementation. Implementation details go stale, but the judgment of "why MySQL" doesn't.

An ADR isn't meeting minutes. Minutes are who said what and what was discussed. An ADR is the outcome, not the process.

An ADR isn't truth. It's a snapshot, recording "in this context, at this time, we judged this choice best." If a better option is found later, write a new ADR to supersede the old one. The old ADR isn't deleted — it records the evolution and is itself part of the context.


When is an ADR worth writing? One test: is this decision irreversible, or expensive to reverse?

Choosing a database, choosing a message queue, deciding monolith vs. microservices, changing API protocols, changing core data models — these are worth writing. Choosing which cache client isn't (too easy to swap). Scaling a service from 2 to 5 instances isn't (that's an ops action, not an architectural decision).

But if you made a seemingly small decision like "the system no longer uses a caching layer; all reads go directly to the database" — that's worth an ADR. Because this decision changes the system's data access patterns, and the cost of reversing it could be high. When in doubt about the cost, err on the side of writing one.

When not to write? Reversible decisions, small-scope implementation details, or when the team is two people who discuss everything daily. Rapid prototypes and experimental code don't need ADRs either — fill them in when committing to the investment.


ADR status changes. Initial: proposed — a decision is put forward for discussion. After review and acceptance: accepted. If a better option is found later, the old ADR is marked deprecated or superseded, with a new ADR explaining why.

The key is that superseded should state "superseded by ADR-008." This way, tracing through ADR files reveals the complete path of architectural evolution — from "why we chose MySQL" to "why we later migrated to PostgreSQL."

Old ADRs are never deleted. A record of "we thought wrong then" is more valuable than a polished document of "we got it right from the start."


ADRs go in the code repository.

Confluence and wikis become documentation graveyards — unmaintained, unread, unsearchable. ADRs in the repo are reviewed and merged alongside every code change. Code changers naturally see ADRs; ADR writers naturally link to code. ADRs evolve with code, rather than dangling on some unvisited wiki page.

Filename convention: docs/adr/ADR-001-title.md. Titles should feel like decisions, not descriptions:

  • Good: ADR-001-use-mysql-as-primary-storage.md
  • Bad: ADR-001-database-selection.md

Because the former shows the decision in the file listing; the latter requires opening to find out.


Writing an ADR takes about 10 minutes. A database selection decided in a one-hour meeting takes 10 minutes to write down. Six months later, someone — possibly you — finds an unexplainable config in the code, opens docs/adr/, finds the matching ADR, and understands why in two minutes.

The ROI on those 10 minutes beats most code optimizations.