Six months after a decision, the code shows what was built — never why, or what else was considered and rejected. RFCs and ADRs exist specifically to capture that missing context, in writing, before it's gone from everyone's memory.
3 min read
Reading a finished piece of code can tell you exactly what it does — but it can almost never tell you what else was considered and rejected, or why this particular approach won out over the alternatives. That reasoning exists only in the heads of the people who made the decision, and fades fast — often well before someone else needs to revisit it, wondering "why was it built this way" with no way to find out except asking around and hoping someone remembers.
An RFC (Request for Comments) is a written proposal circulated before a significant decision is finalized — describing the problem, the proposed approach, the alternatives considered, and their trade-offs (directly building on the previous lesson's habit of naming trade-offs explicitly) — specifically to gather feedback while the decision is still genuinely open, not after it's already been built.
A minimal, practical RFC structure:
# RFC: [Short, specific title]
## Problem
What needs solving, and why now?
## Proposed approach
The actual proposal, in enough detail to evaluate.
## Alternatives considered
What else was considered, and specifically why it was rejected —
not just that it was rejected.
## Trade-offs
What this approach costs, honestly, not just what it gains.
The alternatives section is often the most valuable part months later — it answers "did anyone think of X" definitively, preventing the same idea from being re-litigated repeatedly by different people who didn't know it was already considered and rejected, for reasons that are still written down.
An ADR (Architecture Decision Record) is a shorter, after-the-fact record — capturing a decision that's already been made, so it's findable later. Where an RFC is a proposal soliciting feedback, an ADR is closer to a permanent log entry.
A typical ADR is genuinely short:
# ADR-014: Use Postgres, not MongoDB, for the main application database
## Status
Accepted
## Context
Data is relational (users, orders, order items) with a need for
transactional consistency across related writes.
## Decision
Postgres.
## Consequences
Requires an explicit schema and migrations for changes. Gains
strong consistency guarantees and mature tooling the team already
knows.
The actual return on this habit isn't felt on the day it's written — it's felt the day someone new joins the team and asks "why don't we just use X instead," and instead of re-litigating a settled decision from scratch, someone links ADR-014. It's felt again when a team member reconsiders reversing an old decision and can actually check whether the original reasons for it still hold, rather than trying to reconstruct forgotten context from nothing.
Not every decision warrants an RFC or ADR — a small, easily-reversible choice with limited blast radius doesn't need the ceremony. The right trigger is roughly: decisions that are expensive to reverse, affect multiple people or teams, or that someone is likely to reasonably question later. Writing a full RFC for a trivial, easily-undone choice is itself a version of the "using the most expensive tool for the job" problem covered in the AI & ML Fundamentals domain's fine-tuning-vs-prompting lesson — matching the actual investment to what the decision genuinely warrants.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What's the key difference between an RFC and an ADR?
2. Why is the 'alternatives considered' section of an RFC often the most valuable part months later?
3. According to this lesson, which decisions actually warrant the effort of writing an RFC or ADR?
Software Engineering Fundamentals