Module 3: Communicating Architecture

6. The ADR as communication: the why that travels through time

Overview

By the end of this lesson you'll use the ADR (Architecture Decision Record) as what it is in this module: a communication tool, not a formality. The C4 diagrams you drew in the previous lessons communicate the what very well —what pieces there are, how they connect, what the system looks like today—, but they're completely mute about the why. A Container diagram shows that Mercado's checkout is a separate service; it doesn't say why it was separated, nor what was considered, nor what was sacrificed to achieve it. And that why is precisely what the person who arrives later needs: the dev who in two years inherits checkout and thinks "this would be simpler together with orders". The ADR is the why packaged to travel through time to that person, who wasn't in the room when it was decided and has no one to ask.

This matters because the most expensive knowledge to lose in a system isn't how it's built —that's read from the code and the diagrams— but why it's built this way. The code tells you the final state; it doesn't tell you what alternatives were discarded and for what reason, nor what now-forgotten business constraint forced a decision that seems odd. Without that why, every old decision looks like a whim or a mistake, and the new team falls into two traps: either it undoes good decisions because it doesn't understand their reason (and repeats the pain they solved), or it respects bad decisions out of fear of touching them ("there must be a reason"). The ADR cuts both: it leaves the why written where someone can find it, so decisions can be questioned with knowledge instead of by guesswork.

Connection with the module: in lesson 5 you learned to show the picture of the system at the right level for each audience. Here you add the piece the picture doesn't capture: the story of why the picture looks this way. It's the other half of communicating an architecture —the diagram is the what, the ADR is the why, and a complete communication needs both—. It matters to mark the frontier from now: the mechanics of the ADR —its Context / Decision / Consequences / Status structure, when to write it, how to number it, when to mark it superseded— was taught in the sister guide architecture-decisions-and-tradeoffs. Here we do not re-explain that mechanics: we use it. The novelty of this lesson isn't the ADR's format (you already know it), it's its communicative role: how a well-written ADR speaks to a future reader.

The note the previous owner leaves

Imagine you move into an old house. You understand almost everything just by looking: where the light switches are, how the window opens, what each room is for —that's the what, and it's read from the house itself, like the code is read from the repository—. But there are things the house, no matter how much you look, doesn't explain to you. Why the garage door is walled up. Why there's a pipe that takes the long way around instead of going straight. Why the living-room switch also turns off the hallway light. You look at that and think: "how odd, whoever lived here didn't know what they were doing; I'm going to fix it".

And then you find, stuck inside the fuse box, a note from the previous owner: "I walled up the garage door because it opened onto land that floods; if you open it, water gets in with every storm. The pipe takes the long way because under the straight floor there's a structural beam that can't be drilled. The switch is joined on purpose: the old wiring couldn't support two separate circuits here." Suddenly, what looked like incompetence turns out to be informed decisions facing constraints you couldn't see. The note saved you three expensive mistakes: you'd have unwalled the garage and suffered floods, drilled the beam, and spent money separating a circuit that can't handle it. The previous owner isn't there to explain it to you in person —but their why traveled through time to you, in a note.

That's an ADR. It doesn't document how the house is (you see that on your own); it documents why it made the decisions that seem odd, so whoever arrives later doesn't undo them out of ignorance nor respect them out of superstition, but understands them. An ADR is the note today's architect sticks on the fuse box for the dev of two years from now. And like every good note, its value isn't at the moment of writing it —when everyone knows the why—, but much later, when the one who knew has already left and someone arrives who needs to understand.

What makes an ADR communicate (and not just archive)

The ADR has the same trap as all the documentation in this module: it can be written to archive (fulfill the formality of "we have to document the decisions") or to communicate (so a future human understands). The structure is the same —you learned it in the decisions guide—; what changes is how you fill it in. Three things separate the ADR that communicates from the one that just takes up space:

The Context tells the tension, not the result. The ADR that archives writes "Checkout was coupled". The one that communicates writes "Checkout lived in orders but payments touched it on every change: two squads coordinating the business's most critical flow, the slowest to change right where the money comes in". The difference is that the second makes the future reader feel the pressure that existed —the real pain that justified moving—. Without that tension, the decision seems arbitrary; with it, it seems inevitable.

The Consequences include what hurts. The ADR that archives lists only the benefits ("faster changes, better separation"). The one that communicates also writes the price: "one more network call in the critical path; migrating live requires a dual-write period". This is what really helps the future reader, because it tells them what was known and accepted on purpose. When that future dev notices the extra latency, the ADR will tell them "yes, we knew, it was the conscious price of the separation" —and they won't lose a week investigating a "problem" that was actually a decision—.

The Status says whether it still applies. An ADR marked Accepted tells the reader "this is still current". One marked Superseded by ADR-021 tells them "this already changed, go to 021". That metadata is what prevents someone from taking an old and reverted decision as if it were the current one. The status is the note's expiration date.

Notice that none of the three is about the format —all are about writing thinking of the reader who wasn't there. That's the lesson's twist: the same ADR, filled in to communicate, becomes the note that saves someone from a mistake two years from now.

Worked example: a Mercado ADR, generated as a communication piece

We'll produce the ADR of a real Mercado decision —extracting checkout to its own service, the one we saw born in module 2— treating it as a communication piece. The following code takes the decision as structured data (context, decision, consequences, status) and renders it as a readable ADR. The idea is twofold: to show what an ADR that communicates looks like, and to make clear that an ADR is so structured it can even be generated from data —which makes it easy to version alongside the code, as we'll see in lesson 7—.

# An ADR isn't bureaucracy: it's the WHY of a decision, packaged to travel
# through time to whoever arrives later. Here we GENERATE it as a communication
# piece from structured data (the ADR's mechanics was taught in the
# architecture-decisions guide; here we use it to communicate).

adr = {
    "id": "ADR-014",
    "title": "Extract checkout to its own service",
    "status": "Accepted",
    "date": "2026-03-10",
    "deciders": ["architect", "orders lead", "payments lead"],
    "context": (
        "The checkout module lives in orders but payments touches it on every "
        "change: it's where the order and the charge embrace. Today two squads "
        "must coordinate for any adjustment, and the business's most critical flow "
        "(where the money comes in) is the slowest to change."
    ),
    "decision": (
        "Extract checkout to its own service, with a stream-aligned team owning "
        "the full flow. Orders and payments expose APIs to it; checkout orchestrates them."
    ),
    "consequences_pos": [
        "A single team decides on the most critical flow: faster changes.",
        "The order/payment boundary becomes explicit in a contract, not tangled code.",
    ],
    "consequences_neg": [
        "One more network call in the critical path: latency and failures must be watched.",
        "Migrating checkout live is delicate; it requires a dual-write period.",
    ],
}

def render_adr(a):
    out = []
    out.append(f"# {a['id']}: {a['title']}")
    out.append("")
    out.append(f"**Status:** {a['status']}  |  **Date:** {a['date']}  |  "
               f"**Deciders:** {', '.join(a['deciders'])}")
    out.append("")
    out.append("## Context")
    out.append(a["context"])
    out.append("")
    out.append("## Decision")
    out.append(a["decision"])
    out.append("")
    out.append("## Consequences")
    out.append("For:")
    for c in a["consequences_pos"]:
        out.append(f"- {c}")
    out.append("Against (the price we accept):")
    for c in a["consequences_neg"]:
        out.append(f"- {c}")
    return "\n".join(out)

print(render_adr(adr))
print()
print("-" * 66)
print("This piece fits on one screen. In two years, the dev who inherits the")
print("checkout will read WHY the service exists without having to ask anyone.")
print("That's the ADR as communication: the why, traveling through time.")

What to expect. Running it:

# ADR-014: Extract checkout to its own service

**Status:** Accepted  |  **Date:** 2026-03-10  |  **Deciders:** architect, orders lead, payments lead

## Context
The checkout module lives in orders but payments touches it on every change: it's where the order and the charge embrace. Today two squads must coordinate for any adjustment, and the business's most critical flow (where the money comes in) is the slowest to change.

## Decision
Extract checkout to its own service, with a stream-aligned team owning the full flow. Orders and payments expose APIs to it; checkout orchestrates them.

## Consequences
For:
- A single team decides on the most critical flow: faster changes.
- The order/payment boundary becomes explicit in a contract, not tangled code.
Against (the price we accept):
- One more network call in the critical path: latency and failures must be watched.
- Migrating checkout live is delicate; it requires a dual-write period.

------------------------------------------------------------------
This piece fits on one screen. In two years, the dev who inherits the
checkout will read WHY the service exists without having to ask anyone.
That's the ADR as communication: the why, traveling through time.

Read the generated ADR with the eyes of the future dev, the one from exercise 3 of lesson 1 —the one who looked at the diagram and thought "why is checkout separated from orders if they're so related?"—. That dev opens this ADR and in thirty seconds has the answer the diagram didn't give them: the Context makes them feel the tension (two squads coordinating the money flow), the Decision explains the move (a team owning the full flow), and the Consequences tell them that the extra latency they may be noticing isn't a bug, it's the price that was accepted knowingly. With that, the dev no longer proposes undoing the separation out of ignorance: if anything they question it, they do so with knowledge —knowing what it solved and what it cost—. The diagram showed them the picture; the ADR told them the story. The combination is what really communicates an architecture.

Notice also a practical detail lesson 7 will exploit: since the ADR came from structured data and fits on one screen, it's a small text file that can live in the repository, versioned alongside the code, changing when the decision changes. None of that happens with a 500-page document in a wiki. The ADR is small on purpose: small gets maintained, small gets read, small travels.

The ADR vs. the diagram: what each communicates

It's worth fixing the division of labor, because it's the reason this lesson exists alongside the C4 ones.

Communicates the...Ages...Answers the question of...
Diagram (C4)what — the shape of the system todaywhen the structure changeswhoever needs to orient themselves in the current system
ADRwhy — the reasoning behind italmost never (the decision and its context are historical)whoever needs to understand why the system is this way

There's an interesting asymmetry in the middle column. The diagram describes the present, so it ages every time the system changes —it has to be maintained—. The ADR describes a historical moment —"in March 2026, given these conditions, we decided this"—, and that moment never changes: even if the decision is later reverted, the record that it was made, why, and what was known then remains true forever. That's why an ADR isn't "updated": it's superseded (a new one is written saying "this replaces ADR-014") and the old one is kept as part of the history. History isn't edited; it's added to. That permanence is precisely what lets the ADR travel through time: it's a dated record, not a picture that has to be retouched.

The conclusion for the architect: don't choose between diagram and ADR —use both, because they communicate different things—. The complete communication package of an important decision is the diagram that shows the new shape plus the ADR that explains why. In the project (lesson 8) you'll deliver exactly that combination.

Common mistakes

Writing the ADR afterward, "for the archive" (of formality). What happens: the decision was made months ago, someone remembers "we have to document it", and writes a dry and retroactive ADR that only states the result ("checkout is a separate service") without the tension or the price. No one who reads it later understands the why, because the why isn't there. Why it happens: the ADR is treated as a compliance requirement, not as a letter to a future reader. How to spot it: if your ADR can be summed up as "we decided X" without a "because Y was happening and Z was the risk", it's an archive, not communication. How to fix it: write it close to the decision, when the tension is fresh, and fill the Context with the real pain and the Consequences with the accepted price —that's what the future reader needs—.

Omitting the negative consequences (of selling the decision). What happens: the ADR lists only the benefits, like a brochure for the decision, and stays silent on the price. The future reader runs into that price in practice (the extra latency, the migration complexity) and finds no trace that it was foreseen —so they assume it was an oversight and maybe try to "fix it"—. Why it happens: you want your decision to look good. How to spot it: if your Consequences section has nothing that hurts, you either lied or didn't think the decision through. How to fix it: the most useful part of an ADR for the future is what was sacrificed knowingly; write the price with the same honesty as the benefit, because that's what prevents someone from reopening an already-closed debate.

Confusing the ADR with documentation of how it works (of the wrong level). What happens: the "ADR" fills up with implementation details —endpoints, table schemas, class names— instead of the decision's reasoning. It becomes a technical document that ages fast and doesn't communicate the why. Why it happens: the why (ADR) is mixed with the how (which is code and diagrams). How to spot it: if your ADR has to be updated every time the code changes, it's not an ADR —it's misplaced technical documentation—. How to fix it: the ADR captures the decision and its reason, which are historical and stable; the how lives in the code and the C4 diagrams. A well-made ADR barely changes after being written, because it describes a moment, not a state.

Exercises

Exercise 1 — Rescue the why. A Mercado ADR says, complete: "Decision: We use PostgreSQL for the catalog. Consequences: It's a reliable relational database." A future dev reads it and learns nothing useful. Rewrite it so it communicates, inventing a reasonable context and consequences. What was it missing?

See solution

It was missing the two things that make an ADR communicate: the tension in the context and the price in the consequences. As it stands, it doesn't say why PostgreSQL and not something else, nor what was discarded, nor what was sacrificed —so it's useless to the future dev: they can't question the decision with knowledge nor understand its limits—.

A version that communicates:

ADR-006: PostgreSQL for the catalog Status: Accepted — 2025-11 Context: The catalog needs complex relational queries (filters by category, price, seller, stock) and consistency guarantees on the inventory —it can't sell what doesn't exist—. We evaluated a document database (MongoDB), but our queries are intrinsically relational and we need transactions for the stock. The team already knows PostgreSQL deeply. Decision: PostgreSQL as the catalog database, with text search delegated to a separate index (Elasticsearch) where the relational doesn't help. Consequences:

  • For: solid relational queries and transactions; the team is productive from day one.
  • The price: free-text search requires a second system (Elasticsearch) and keeping both in sync; PostgreSQL alone wouldn't have been enough for that.

Now the future dev understands why PostgreSQL (relational queries + transactions + expertise), why not a document database (it was considered, didn't fit), and why there's an Elasticsearch alongside (the price of PostgreSQL not doing text search well). With that they can make informed decisions; with the original ADR, they can't.

Exercise 2 — Diagram or ADR. For each question a new dev in Mercado asks themselves, say whether a C4 diagram or an ADR answers it better, and why: (a) "what pieces make up the system and how do they connect?"; (b) "why is checkout a separate service and not part of orders?"; (c) "what technology is the API built with?"; (d) "why didn't we use microservices for everything from the start?".

See solution
  • (a) "What pieces and how do they connect?" → Diagram (Container). It's a question about the current shape of the system —the what—. The Container answers it at a glance. An ADR here would be the wrong level.
  • (b) "Why is checkout a separate service?" → ADR. It's a question about the why of a decision —exactly what the diagram doesn't capture—. ADR-014 tells them the tension (two squads coordinating the money flow) and the reason. The diagram would only show them that it is separated, not why.
  • (c) "What technology is the API built with?" → Diagram (Container). The what again; each piece's technology is in the Container ("API — FastAPI"). No ADR needed.
  • (d) "Why not microservices from the start?" → ADR. It asks for the reasoning behind a structural decision (start with a monolith, extract services only when it hurts). That's a historical why —perhaps an early ADR that explains "we started monolith because we were one team and didn't have clear boundaries; we extract services when the organization justifies it"—. Today's diagram doesn't explain it.

The pattern: questions of what/how it looks/with what → diagram; questions of why it's this way/why not another way → ADR. The two together answer everything.

Exercise 3 — The decision that was reverted. A year ago, Mercado wrote ADR-014 (extract checkout). Today, after learning that the extra latency caused cart abandonment, the team decides to revert and re-integrate checkout into orders. A dev proposes: "let's delete ADR-014, it no longer applies, so as not to confuse". Is it correct to delete it? What should be done, and why does it matter for communication over time?

See solution

It should not be deleted. Deleting ADR-014 destroys precisely what makes the record valuable: the story of why it was made and why it was reverted. If you delete it, in a year someone could propose again extracting checkout —without knowing it was already tried, that the latency caused cart abandonment, and that's why they went back—. They'd repeat the experiment and the pain. The most expensive knowledge (what we already tried and it didn't work) would be lost.

The right thing, according to the mechanics you learned in the decisions guide: mark ADR-014 as Superseded and write a new ADR —say ADR-027, "Re-integrate checkout into orders"— that explains the new context (the extra latency caused measurable cart abandonment), the new decision (re-integrate), and its relation to the old one ("supersedes ADR-014"). ADR-014 is kept, now with a status that says "this no longer applies, go to ADR-027".

Why it matters for communication over time: the chain ADR-014 → ADR-027 tells the future reader the complete story —it was separated for these reasons, it was reverted for these others—, which is infinitely more useful than either of the two decisions alone. A future architect considering separating checkout will read both and know exactly what to watch (the latency) if they try it again. History isn't edited or deleted: it's added to. A reverted ADR isn't garbage; it's the most expensive lesson the team learned, kept so it doesn't repeat.

Summary and next step

In this lesson you used the ADR as a communication tool: the why of a decision, packaged to travel through time to whoever arrives later. With the previous owner's note in the house you saw that what the house (the code, the diagrams) can't explain on its own —why the odd decisions were actually informed— is exactly what the ADR keeps, preventing whoever arrives from undoing the good out of ignorance or respecting the bad out of superstition. You generated, executed, Mercado's ADR-014 as a piece that communicates: with the tension in the context, the price in the consequences, and the status that says whether it still applies. And you fixed the division of labor: the diagram communicates the what (and ages with the system), the ADR communicates the why (and is a historical record that isn't edited, it's superseded).

Before moving on you should be able to: write an ADR that communicates (tension in the context, price in the consequences, current status) and doesn't just archive; decide whether a question is answered with a diagram or an ADR; and handle a reverted decision without deleting the history (superseded + new ADR).

What follows is the vaccine. You already know how to produce good communication —the diagrams at the right level, the ADR with the why—; what's left is to learn to not produce the bad. In lesson 7 you'll attack the two big failures of architecture communication: the 500-page document no one reads (documenting too much, communicating too little) and the spaghetti diagram that shows everything and communicates nothing. You'll run two validators over Mercado —one that detects a diagram mixing abstraction levels, another that counts elements and flags the spaghetti when it passes the legible limit— and understand why a diagram rots if it doesn't live versioned alongside the code. It's the step from "I know how to communicate well" to "I know how to recognize and avoid the two ways of communicating badly".

Resources