Every project accumulates decisions. What to build, why it matters, which database to use, whether to break the monolith. The problem isn’t making those decisions — it’s that six months later nobody remembers why you made them.
That’s where three little acronyms come in: PRD, ADR, and RFC. They get thrown around interchangeably, but they answer three completely different questions:
- PRD — What are we building, and why?
- RFC — Here’s how I propose we build it. What does everyone think?
- ADR — We decided X, for these reasons. Here’s the record.
Get them confused and you’ll write a 20-page PRD when a one-page ADR would do, or open an RFC for a decision that was already made. This guide covers what each one is, how they fit together, best practices for writing them, and a side-by-side comparison table.
PRD — Product Requirements Document
A PRD captures what you’re building and why — before anyone writes a line of code. It’s a product artifact, not a technical one. It describes the user problem, the intended solution, success metrics, and scope, and it deliberately avoids prescribing implementation details.
Think of the PRD as the shared source of truth for a feature or product. Product, engineering, design, and stakeholders all align on it before work starts.
What goes in a PRD
- Problem statement — the user pain or business opportunity
- Goals and non-goals — what success looks like, and what’s explicitly out of scope
- User stories / requirements — what the product must do
- Success metrics — how you’ll know it worked
- Constraints and assumptions — timelines, dependencies, known unknowns
What a PRD should not contain
Technical design. The moment a PRD starts specifying database schemas or API contracts, it’s doing an RFC’s or ADR’s job. Keep it focused on the what and the why.
💡 Pro tip: A good PRD is measured by the questions it prevents. If engineering keeps coming back with “but what happens when…”, your PRD hasn’t done its job yet.
PRD template
Copy this, fill in the blanks, delete the guidance comments:
# PRD: <Feature / product name>
- **Author:** <name> **Status:** Draft | In review | Approved
- **Last updated:** 2026-08-09 **Stakeholders:** <PM, eng lead, design>
## Overview
One paragraph: what this is and who it's for.
## Problem
The user pain or business opportunity. Include evidence
(support tickets, metrics, research) — not just opinion.
## Goals
- <Measurable outcome we want>
- <Another outcome>
## Non-goals
- <What we are explicitly NOT doing this cycle>
## Requirements / User stories
- As a <user>, I want <capability> so that <benefit>.
- <Prioritize: Must / Should / Could>
## Success metrics
- <Metric + target, e.g. "activation rate +10% in Q3">
## Constraints & assumptions
- <Deadlines, dependencies, platform limits, known unknowns>
## Open questions
- <Unresolved decisions to close before build>
Best practices
- Lead with the problem, not the solution. If the reader can’t restate the user problem after the first paragraph, rewrite it.
- Make non-goals explicit. Scope creep starts where non-goals are vague.
- Tie every requirement to a metric. A requirement you can’t measure is a wish.
- Keep it living during discovery, frozen at commitment. Iterate freely before build starts; once the team commits, changes should be deliberate and tracked.
RFC — Request for Comments
An RFC is a proposal opened up for feedback. You’ve got an idea for how to solve a problem — a new service, an API redesign, a migration — and instead of just building it, you write it down and invite the team to poke holes in it before you commit.
The name comes from the IETF, where internet standards (like HTTP) have been published as RFCs for decades. In a company setting, an RFC is how you turn one engineer’s opinion into a team decision — with the debate captured in writing rather than lost in a Slack thread.
What goes in an RFC
- Context / problem — what you’re trying to solve
- Proposal — the design you’re advocating for
- Alternatives considered — other approaches and why you rejected them
- Trade-offs and risks — what this costs you
- Open questions — where you specifically want feedback
The lifecycle
An RFC is a living document during its comment period. People leave feedback, you revise, and eventually it reaches a resolution: accepted, rejected, or superseded. Once resolved, the discussion is archived — the value is as much in the recorded debate as in the outcome.
RFC template
# RFC: <Short, descriptive title>
- **Author:** <name> **Status:** Draft | In review | Accepted | Rejected
- **Created:** 2026-08-09 **Decision by:** <date> **Owner:** <decision-maker>
## Summary
Two or three sentences: what you're proposing and why.
## Context / Problem
Background the reader needs. What's broken, missing, or forcing
this change? Link to the PRD or issue that prompted it.
## Proposal
The design you're advocating for, in enough detail to critique.
Diagrams, API sketches, data models — whatever makes it concrete.
## Alternatives considered
- **Option A — <name>:** why it was rejected.
- **Option B — <name>:** why it was rejected.
(Real alternatives, not straw men.)
## Trade-offs & risks
What this costs us: complexity, migration effort, performance,
lock-in. Be honest — this is where reviewers focus.
## Open questions
- <Where you specifically want feedback>
## Decision
Filled in when resolved: what was decided, by whom, and any
follow-up ADRs it produced.
Best practices
- Write it to be argued with. Present real alternatives, not straw men. The point is to surface disagreement early.
- Set a review deadline. Open-ended RFCs die in limbo. Give people a date.
- Name the decision-maker. Consensus is the goal, but someone needs the authority to close the discussion.
- Link to it forever. When the decision lands, the RFC becomes the “why” that future engineers will search for.
⚠️ Warning: An RFC is for decisions not yet made. If you’ve already built the thing and you’re writing an RFC to rubber-stamp it, you’re not gathering feedback — you’re theater. Write an ADR instead.
ADR — Architecture Decision Record
An ADR is a short, focused record of a single architectural decision: what you chose, the context that forced the choice, the alternatives, and the consequences. One decision, one record.
The defining trait of an ADR is that it’s immutable. Once accepted, you don’t edit it. If the decision changes later, you write a new ADR that supersedes the old one — leaving a clear historical trail of how your architecture evolved.
ADRs typically live in the repo itself (docs/adr/0001-use-postgres.md), numbered sequentially, so they travel with the code they describe.
The classic ADR template
Popularized by Michael Nygard, the format is deliberately minimal:
# 1. Use PostgreSQL for primary datastore
Date: 2026-08-09
## Status
Accepted
## Context
We need a relational store with strong consistency and JSON support...
## Decision
We will use PostgreSQL 16 as the primary datastore.
## Consequences
- We gain rich querying and JSONB flexibility.
- We take on operational overhead for HA and backups.
- Team already has Postgres experience — low ramp-up.
Best practices
- One decision per record. If you’re documenting three choices, write three ADRs.
- Keep it short. An ADR should fit on a page. If it’s growing, it probably wanted to be an RFC first.
- Never rewrite history. Superseding decision changed? New ADR, marked
Superseded by ADR-0012. The old one stays. - Store it with the code. ADRs in the repo get read; ADRs in a wiki get forgotten.
- Capture consequences honestly. The costs and trade-offs are the most valuable part for future readers.
How They Fit Together
These three aren’t competitors — they form a pipeline that follows a decision from intent to record:
PRD RFC ADR
"what & why" → "how? let's debate" → "here's what we
(product intent) (proposal + feedback) decided, forever"
- A PRD establishes what the product needs and why — the intent.
- To implement it, an engineer opens an RFC proposing how, and the team debates alternatives.
- When the RFC resolves, the resulting architectural choices get captured as ADRs — the permanent record.
Not every change needs all three. A tiny bug fix needs none. A new product line might need a PRD, several RFCs, and a dozen ADRs. Right-size the ceremony to the stakes.
💡 Pro tip: These documents are also gold for AI coding agents. A PRD gives an agent the intent, an RFC gives it the accepted approach, and ADRs give it the constraints it must respect. This is exactly the kind of durable context that spec-driven development is built on.
Comparison Table
| Characteristic | PRD | RFC | ADR |
|---|---|---|---|
| Question it answers | What are we building, and why? | How should we build it? | What did we decide, and why? |
| Domain | Product | Technical design | Architecture |
| Typical author | Product manager | Any engineer | Engineer / architect |
| Primary audience | Cross-functional (eng, design, stakeholders) | The team, for feedback | Engineers & future maintainers |
| Timing | Before design & build | Before committing to a design | At the moment of decision |
| Focus | User problem, requirements, metrics | Proposal + alternatives, open for comment | One decision + consequences |
| Length | Medium–long | Medium–long | Short (≈1 page) |
| Mutability | Living, then frozen at commitment | Living during review, then resolved | Immutable — superseded, never edited |
| Process | Alignment / sign-off | Comment & consensus | Recorded (often after an RFC) |
| Where it lives | Product docs / PM tool | Docs repo or wiki | In the code repo (docs/adr/) |
| Lifespan | Life of the feature/product | Archived after decision | Permanent historical record |
Which One Do You Need?
- Aligning on what to build? → PRD
- Proposing how to build it and want feedback? → RFC
- Recording a technical decision you’ve made? → ADR
- A one-line change with no real trade-offs? → None. Just ship it.
The goal of all three is the same: make the reasoning behind your work durable, so that Future You — and your teammates, and your AI agents — don’t have to reverse-engineer it from the code.
Start small. Add ADRs to your repo first (they’re the cheapest, highest-value habit). Reach for RFCs when a decision deserves a debate. Write PRDs when the cost of building the wrong thing is high.
Related Documents
PRD, RFC, and ADR aren’t the whole landscape — a few adjacent documents come up constantly and get conflated with these three.
Design Doc. The one most often confused with an RFC. A Design Doc (popularized by Google’s engineering culture) is a single-author (or small-team) detailed technical design for one project — it goes through review and approval, but it isn’t built around open, team-wide debate over alternatives the way an RFC is. If your “RFC” always has exactly one obvious answer and nobody ever proposes a real alternative, you’re probably writing a Design Doc with an RFC label on it. Neither is wrong — just be honest about which one you’re doing.
One-Pager / Pitch. A lightweight, pre-PRD document: is this idea worth pursuing at all? It skips requirements and metrics in favor of a quick problem statement and rough shape of a solution, just enough to get a go/no-go before anyone invests in a full PRD. If your PRDs take weeks to align on, you’re probably missing this step.
Postmortem / RCA (Root Cause Analysis). Structurally similar to an ADR — short, focused, lives in the repo or a wiki — but retrospective instead of prospective. It records what happened during an incident, why, and what’s changing as a result, rather than a decision made in advance. Don’t lump it in with ADRs when organizing your docs; the audience and the trigger for writing one are different (an outage, not a design choice).
None of these need a spot in your day-to-day PRD → RFC → ADR pipeline. But knowing where they diverge means you’ll reach for the right template instead of stretching one document to do a job it wasn’t built for.