Writing RFCs That Survive Design Review
An RFC that survives design review states the problem, the options, and a justified decision, not just a chosen design. The structure and the failure modes.
Part of Staff Engineer Craft: Design, Influence, and Learning
An RFC that survives design review does one thing the rejected ones do not: it shows the thinking, not just the conclusion. Writing RFCs that get approved means stating the problem clearly, laying out the real alternatives with honest tradeoffs, and justifying your recommendation against them. A document that presents a single design as if no others existed gives reviewers nothing to evaluate, and that is why it stalls.
The RFC is how senior engineers drive technical decisions at scale, because it moves the debate to before the code is written, when changing course is cheap. A good one builds alignment; a bad one generates a hundred review comments and a stalled project.
Why RFCs are how senior engineers scale their impact
Writing code changes one system. Writing an RFC that aligns a team changes the direction of many. As you grow into senior and staff roles, your impact increasingly comes from decisions you influence rather than code you personally write, and the RFC is the primary instrument for that influence.
The RFC also front-loads disagreement to the cheapest possible moment. A design flaw caught in review costs a comment; the same flaw caught after implementation costs a rewrite. A culture that writes RFCs is a culture that argues on paper before it builds, which is far cheaper than arguing in code. This post is part of the Staff engineer craft series.
What should an RFC include?
A strong RFC has a problem statement, goals and non-goals, the proposed design, alternatives considered with their tradeoffs, the impact on adjacent systems and teams, and open questions. The sections people skip, alternatives and non-goals, are precisely the ones that separate an RFC from a design doc that merely describes one solution.
A dependable structure:
- Problem statement. What are we solving, and why now? No solution yet.
- Goals and non-goals. What success means, and explicitly what is out of scope.
- Proposed design. The recommendation, in enough detail to evaluate.
- Alternatives considered. The real other options, each with honest pros and cons.
- Tradeoffs and risks. What this choice costs, and what could go wrong.
- Impact. Which other systems, teams, and on-call rotations are affected.
- Open questions. What you are still unsure about.
The discipline of writing the alternatives section honestly often changes the recommendation, which is the point: the RFC is a thinking tool, not just a communication tool.
What makes an RFC survive design review?
Three things: a problem framed so clearly that reviewers agree on what is being solved, alternatives presented fairly enough that the chosen one is visibly the best of real options, and a recommendation justified against those alternatives rather than asserted. Reviewers approve proposals where they can see the author understood both the problem and the option space.
The subtle move is to present the alternatives you rejected at their strongest, not as strawmen. When a reviewer sees their preferred option represented fairly and addressed honestly, they trust your conclusion. When they see it strawmanned, they fight you, and the review degrades into defending the framing instead of evaluating the decision.
Why do RFCs get rejected in design review?
Most rejected RFCs fail the same few ways: they jump to a solution without framing the problem, present only one option, ignore tradeoffs and failure modes, or omit the impact on other teams. In each case the reviewer cannot evaluate the decision, because the reasoning behind it is missing or one-sided.
The common failure modes, and their fixes:
| Failure mode | Why it fails | Fix |
|---|---|---|
| Solution-first, no problem framing | Reviewers don’t agree on the goal | Lead with the problem, no solution |
| Only one option presented | Looks like a decision seeking a rubber stamp | Add real alternatives with tradeoffs |
| No tradeoffs or risks | Reads as naive or hiding the downside | State what the choice costs |
| Ignores cross-team impact | Surprises and blocks adjacent teams | Add an impact section |
| Too long, no summary | Reviewers can’t engage | Lead with a tight summary |
The pattern is that rejection usually comes from missing context, not from a bad decision. Give reviewers the problem, the options, and the reasoning, and even a debatable recommendation gets a productive review instead of a wall of objections.
Writing for the reviewer, not the archive
An RFC is read by busy people, so it should open with a short summary that lets a reviewer grasp the problem and recommendation in a minute, then provide the depth for those who need it. The same skim-first, depth-on-demand principle that makes good documentation makes good RFCs: respect the reader’s time, and more people will actually engage with it.
Tone matters too. Write with conviction but not defensiveness; you are inviting comment, which is the whole name of the format. The strongest RFCs read as a confident recommendation that genuinely wants to be challenged, because the author would rather find the flaw in review than in production. That posture, decisive but open, is the same one that makes a system design interview go well, and it is the same judgment a staff-level postmortem demands.
When should you write an RFC?
Write one when a decision is hard to reverse, affects more than one team, or is likely to be contentious. Those three conditions, high cost of being wrong, cross-team impact, or genuine disagreement, are exactly when writing down the reasoning and gathering feedback before building pays off. Small, local, easily-reversible decisions do not need an RFC, and forcing one for everything just creates process for its own sake.
The test is the cost of changing your mind later. Choosing a data store for a new platform, changing an API contract many services depend on, or picking a cross-team standard all carry a high reversal cost, so it is worth arguing on paper first. Renaming an internal function or picking a library for one isolated module does not; just do it and move on. Matching the weight of the process to the weight of the decision is itself a senior judgment.
There is also a timing element. The RFC should come early enough that feedback can still change the design, not after implementation is half done and the document is really a justification. An RFC written too late is theater; one written at the decision point, when the options are still genuinely open, is when it does its real work of surfacing disagreement while changing course is still cheap.
An RFC checklist
Before you circulate an RFC for review:
- It opens with a one-paragraph summary of the problem and recommendation.
- The problem is framed before any solution appears.
- Goals and explicit non-goals are stated.
- At least two real alternatives are presented, steelmanned, with honest tradeoffs.
- The recommendation is justified against those alternatives, not asserted.
- Risks, failure modes, and cross-team impact are covered.
- Open questions are listed honestly rather than hidden.
- It is skimmable: a reviewer can get the gist in a minute.
What makes reviewers reject an RFC?
Rejections cluster into a small number of causes, and almost all are about the document rather than the idea.
The problem is not established. The document opens with a solution and never makes the reader feel the problem. Reviewers cannot evaluate a proposal without a shared understanding of what is wrong today, so they default to questioning the solution — which reads as resistance and is actually confusion.
Alternatives were not considered seriously. One real option and two straw men is transparent, and it costs you credibility for the rest of the document. Reviewers want evidence you explored the space, and a genuinely close alternative that you rejected for a stated reason is the strongest signal you did.
The scope is unclear. Without an explicit non-goals section, every reviewer imagines a different boundary and half the discussion is people objecting to things you never intended to build.
The cost is missing or implausible. No migration plan, no operational burden, no estimate of effort. A proposal that appears to have no cost reads as one that has not been thought through, and it invites the reviewer to find the cost for you.
It is too long. A twenty-page RFC gets skimmed, and skimmed documents get rejected on the objection that happened to catch someone’s eye. Length is not thoroughness — it frequently signals that the author has not yet decided what matters.
No decision is actually requested. The document explores a space and ends. Reviewers do not know what they are approving, so they approve nothing.
The reframing that fixes most of these: an RFC is a request for a decision, not a description of a design. Everything in it should serve the reader’s ability to say yes, no, or “yes if.” State the problem, state the recommendation, show that you understood the alternatives, name the costs honestly, and make the decision being asked for unmistakable.
How do you get an RFC approved before the meeting?
The design review meeting is where an RFC is ratified, not where it is decided. Documents that arrive cold get argued about; documents that arrive with objections already resolved get approved. The difference is entirely in what happens beforehand.
The sequence that works:
- Talk to the one or two people most likely to object, before writing. Not to persuade them — to understand what they will say. Their objection is usually about a constraint you did not know, and learning it now is far cheaper than discovering it in review.
- Write the draft, and address those objections explicitly in the text. Naming a concern and answering it demonstrates that you engaged rather than avoided, and it prevents the concern being raised as though it were new.
- Circulate early, while it is visibly a draft. People engage more honestly with something unfinished. A polished document invites approval or rejection; a draft invites collaboration, and the feedback is better.
- Resolve comments in the document, not in a thread nobody will read later. The RFC should contain the reasoning, including the paths not taken and why.
- Enter the meeting with the major stakeholders already aligned, so the session confirms a decision rather than making one under time pressure.
The instinct this fights is the desire to present finished work. It feels stronger and it is weaker: a document that surprises its reviewers will be evaluated on the surprise rather than on the merits, and people asked to approve something they are seeing for the first time reasonably default to caution.
Two smaller mechanics that matter more than they should. Send it far enough ahead that reading is possible — a document circulated the night before is a document nobody read, and the meeting becomes a reading session. And state the decision you want at the top, so anyone who reads only the first paragraph still knows what is being asked of them, which for senior reviewers is a realistic assumption.
What should an RFC actually contain?
A structure that works, and which is short enough that people read all of it:
| Section | Purpose | Length |
|---|---|---|
| Summary | The problem and the recommendation, for someone who reads nothing else | A paragraph |
| Context / problem | Why this needs solving now, with evidence | Half a page |
| Goals and non-goals | The boundary of what is being decided | A short list |
| Proposal | What you are recommending, concretely enough to build | The bulk |
| Alternatives considered | Real options, with the reason each was not chosen | Several paragraphs |
| Migration plan | How you get from today to there, incrementally | Half a page |
| Risks and open questions | What could go wrong, what you do not know yet | A short list |
Two sections carry disproportionate weight. Alternatives considered is where reviewers decide whether to trust your judgement — a genuinely close alternative, honestly evaluated, is worth more than any amount of advocacy for your preference. And migration plan is where most proposals quietly fail, because a design that cannot be reached incrementally from the current system is not implementable regardless of how good the destination is.
Risks and open questions is the section authors most want to omit and should not. Naming what you are unsure about is not weakness; it directs review effort to where it is genuinely useful and pre-empts the reviewer who was going to raise it anyway. An RFC with no open questions reads as one where the author has not looked hard enough.
On length: aim for something a busy reviewer can read in fifteen minutes. If the material genuinely exceeds that, put the detail in an appendix and keep the decision-relevant material in the body. Reviewers who cannot finish a document approve it reluctantly or not at all.
When is an RFC the wrong tool?
Writing one has a cost — the author’s time, every reviewer’s attention, and the delay before work starts — so it is worth being clear about when that cost is not repaid.
An RFC is warranted when a decision is hard to reverse, affects multiple teams, or commits significant time. Choosing a datastore, changing an inter-service contract, introducing a new language, restructuring a boundary: all qualify, because the cost of being wrong greatly exceeds the cost of the document.
It is the wrong tool when:
- The decision is easily reversed. A library choice inside one service that could be swapped in a day does not need a review. Just make it, and note the reasoning in the pull request.
- You already know what you will do and no one disagrees. Writing an RFC to ratify a foregone conclusion is theatre, and it teaches people that RFCs are performative rather than genuine decision points.
- The problem is not yet understood. A document written to figure out what you think produces a confused reader. Prototype first, then write about what you learned.
- It is genuinely urgent. During an incident, act and document afterwards. An RFC is a deliberation tool and deliberation is not what an outage needs.
The failure mode at both extremes is worth naming. Too few RFCs means consequential decisions get made in pull requests where the only reviewers are people already deep in the code, and the organisation learns about the choice when it becomes a constraint. Too many means the process becomes a tax, people route around it, and the ones that genuinely matter get the same skim as the routine ones.
The calibration question that works: would I want a written record of why we chose this, two years from now, when the person who decided has left? If yes, write it. If the answer is that nobody will care, the decision was reversible enough not to need one.
How do you write for a reviewer who will skim?
Most reviewers read an RFC once, quickly, in a gap between other work. Writing for that reader is a craft skill and it is the difference between a document that gets a decision and one that gets a “let’s discuss.”
Put the recommendation in the first paragraph. Not the background, not the history — what you propose and why. Readers who stop there should still know what is being asked.
Make it scannable. Headings that state conclusions rather than topics, short paragraphs, and tables where you are comparing things. A reviewer should be able to reconstruct your argument from the headings alone.
Use concrete numbers. “This would reduce p99 latency from 800 ms to under 200 ms” is evaluable; “significantly faster” is not. Where you do not have the number, say so and say how you would get it — that is more credible than a confident adjective.
Cut the throat-clearing. Background sections that recount history everyone knows push the substance below the fold. Assume your reader has context; link to it rather than reproducing it.
One decision per document. An RFC bundling three loosely-related decisions gets stuck on whichever is most contentious, and the other two — which everyone agreed with — are blocked with it. Split them.
The test worth applying before you circulate: hand it to someone uninvolved and ask what is being decided and what you recommend. If they cannot answer both in fifteen seconds, the structure is wrong regardless of how good the analysis is. That is a fixable problem, and it is much cheaper to fix before six people have read it than after.
What I’d do differently
The mistake I made early was treating the RFC as a document to justify a decision I had already locked in. That produces a defensive, one-option proposal that invites exactly the contentious review it was meant to prevent, because reviewers can feel when they are being asked to ratify rather than evaluate.
If I were writing RFCs again from the start, I would treat the alternatives section as the real work, not a formality, and write it before I was attached to an answer. Doing the honest comparison first sometimes changes the recommendation and always makes it more defensible, because by review time you have already argued both sides yourself. An RFC that has genuinely considered the alternatives does not need to defend itself; the reasoning does it for you.
Sources
- Google, Design Docs (engineering practices): google.github.io/eng-practices
- IETF, How to write an RFC (the original RFC tradition): ietf.org/standards/rfcs
- Google SRE Workbook (design and review practices): sre.google/workbook/table-of-contents
Frequently asked questions
What is an engineering RFC?
An RFC (request for comments) is a written design proposal that states a problem, the options considered, and a recommended decision with its rationale, circulated for feedback before implementation. It exists to make the thinking reviewable and to build alignment before code is written.
What makes an RFC survive design review?
Framing the problem clearly, presenting real alternatives with honest tradeoffs, and justifying the recommendation against them. Reviewers approve proposals that show the author understood the problem and the options, not proposals that present one design as if no others existed.
What should an RFC include?
A problem statement, goals and non-goals, the proposed design, alternatives considered with tradeoffs, the impact on other systems, and open questions. The alternatives and non-goals sections are what separate a strong RFC from a design doc that just describes one solution.
Why do RFCs get rejected in design review?
Usually because they jump to a solution without framing the problem, present only one option, ignore tradeoffs and failure modes, or skip the impact on adjacent teams. Reviewers cannot evaluate a decision they cannot see the reasoning behind.
Why do RFCs get rejected in design review?
Usually because the problem was never established, alternatives were straw men, scope had no explicit non-goals, costs and migration were missing, the document was too long to read properly, or no specific decision was requested. An RFC is a request for a decision, not a description of a design.
How do you get an RFC approved before the design review?
Talk to likely objectors before writing, address their concerns explicitly in the text, circulate while it is visibly a draft so people engage honestly, resolve comments in the document rather than in threads, and enter the meeting already aligned. A document that surprises reviewers is evaluated on the surprise.
What sections should an RFC contain?
A summary with the problem and recommendation, context with evidence, goals and non-goals, the proposal, alternatives considered with reasons for rejection, a migration plan, and risks and open questions. Alternatives and migration carry the most weight, and it should be readable in fifteen minutes.
When should you not write an RFC?
When the decision is easily reversed, when nobody disagrees and it is a foregone conclusion, when the problem is not yet understood and you should prototype first, or when it is genuinely urgent. The test is whether you would want a written record of the reasoning two years from now.
How do you write an RFC for a reviewer who will skim it?
Put the recommendation in the first paragraph, use headings that state conclusions rather than topics, prefer concrete numbers over adjectives, cut background everyone already has, and keep it to one decision per document. Test it by asking an uninvolved reader what is being decided.