Engineering Strategy

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
Writing RFCs that survive design review, shown as a structured glowing document with one amber approved section

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:

  1. Problem statement. What are we solving, and why now? No solution yet.
  2. Goals and non-goals. What success means, and explicitly what is out of scope.
  3. Proposed design. The recommendation, in enough detail to evaluate.
  4. Alternatives considered. The real other options, each with honest pros and cons.
  5. Tradeoffs and risks. What this choice costs, and what could go wrong.
  6. Impact. Which other systems, teams, and on-call rotations are affected.
  7. 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 modeWhy it failsFix
Solution-first, no problem framingReviewers don’t agree on the goalLead with the problem, no solution
Only one option presentedLooks like a decision seeking a rubber stampAdd real alternatives with tradeoffs
No tradeoffs or risksReads as naive or hiding the downsideState what the choice costs
Ignores cross-team impactSurprises and blocks adjacent teamsAdd an impact section
Too long, no summaryReviewers can’t engageLead 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 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

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.

Newsletter

Liked this breakdown?

Production wisdom on distributed systems, delivered when there is something worth saying. No spam, unsubscribe anytime.