RFC template: an engineering request for comments, with an example

An RFC template for engineering teams: summary, problem, proposal, alternatives, open questions, a comment log and the decision, with a filled-in example.

By Strokes Team · · 10 min read

The template open in Strokes: the title “RFC-[NNNN]: [The proposal in a few words]”, then a details table for Status, Author, Decider and Reviewers and the heading “Summary”.
Table of contents
  1. When to use it
  2. A filled-in RFC example
  3. How to use this template
  4. What goes in each section
  5. RFC statuses from Draft to Accepted
  6. RFC formats and samples
  7. Write requirements with MUST and SHOULD
  8. Frequently asked questions

When to use it

  • A change that affects several teams, such as retiring an API version or a shared library
  • A new rule the whole engineering group will follow: code review, branching, on-call
  • A proposal that needs a named decider and a deadline instead of an open-ended thread
  • Open-source projects that take proposals from contributors in a public repository
  • Recording why a proposal was accepted or turned down, for whoever asks next year

An RFC (request for comments) is a short proposal a team circulates before it makes a decision: the problem, what you propose, what else you considered, what is still open and the date comments close. This RFC template adds the parts most engineering RFCs leave out: a named decider, a status that moves from Draft to Accepted or Rejected, a comment log that shows how each objection was handled, and a decision section, so the finished document records why the team said yes or no.

Use it for changes that need agreement beyond your own team. If the change is agreed and the open question is how to build it, write a design doc. If the decision is already made and only needs recording, a decision record is shorter. The RFC sits between the two: it asks.

A filled-in RFC example

Here is the template filled in for an invented company retiring the first version of its public API. It is shortened for this page, but every section of the template is represented. The proposal lines use the capitalized key words MUST, SHOULD and MAY, explained further down.

RFC-0087: Retire version 1 of the public API · Header, summary, problem

Status: Accepted with changes · Author: Dana Whitfield, API platform · Decider: Marcus Oyelaran, VP of Engineering · Reviewers: Support, Developer relations, Security, Billing · Comments: 20 October to 3 November 2026

Summary. We propose to switch off version 1 of the public API on 30 September 2027. From 1 December 2026, every v1 response will carry Deprecation and Sunset headers, and accounts still calling v1 will get a monthly email with their own call counts and a link to the migration guide.

Problem. v1 and v2 run on separate code paths. v1 still carries 14 percent of API traffic, from 312 accounts. Three of last quarter's five API incidents started in v1-only code, and every new feature is either built twice or left out of v1. Keeping v1 alive costs about one engineer's time.

Original example, written for this template. The company, people and figures are invented.
Proposal and alternatives
  1. v1 MUST stop responding on 30 September 2027. Later requests get 410 Gone with a link to the migration guide.
  2. From 1 December 2026, every v1 response MUST include the Deprecation and Sunset headers.
  3. We SHOULD run two one-hour brownouts, in June and August 2027, each announced a month ahead on the status page and in the changelog.
  4. An account with more than 10,000 v1 calls a month MAY ask for one 90-day extension, approved by the API platform lead.
  5. v1 MUST keep receiving security fixes until it is switched off.

Alternatives considered, all rejected. Do nothing: no work for customers, but the cost and the incidents stay. Switch off in six months: faster savings, but Support expects about 40 accounts could not migrate in time. Freeze v1 with no end date: cheaper than today, but two code paths for good.

#FromCommentResolution
#1FromSupportCommentTwelve months is too short for enterprise accounts on annual contracts.ResolutionChanged: switch-off moved from March to September 2027; extension rule added (proposal 4).
#2FromSecurityCommentWill v1 get security fixes until the end?ResolutionChanged: added as proposal 5.
#3FromDeveloper relationsCommentUnannounced brownouts will look like outages.ResolutionChanged: brownouts announced a month ahead (proposal 3).
#4FromBillingCommentCan we offer migration credits?ResolutionNot adopted: out of scope. Billing may open its own RFC.
The comment log from the same RFC.
Decision

Accepted with the changes from comments 1 to 3, by Marcus Oyelaran on 5 November 2026. Two code paths cost more every quarter, and the incident record outweighs the migration work; ten months' notice before the first brownout is enough for the accounts Support has spoken to. Follow-up: migration guide and changelog entry (Developer relations, 1 December 2026), customer emails (Support, 1 December 2026), an SDK release that warns when v1 is called (15 January 2027).

Revisit if: more than 50 accounts still send v1 traffic on 1 June 2027, or the June brownout shows a customer can't migrate without a contract change. Either one sends the switch-off date back to the decider before the August brownout.

Why it works. The summary is the whole decision in two sentences. The problem uses numbers anyone can check, and each proposal line carries one key word, so reviewers can see which lines are firm and which are negotiable. Rejected options are recorded in two places: the alternatives, each with its cost, and the log's fourth comment, not adopted and why. The log shows what each objection changed, and the decision ends with the evidence that would reopen it, so a reviewer who disagrees knows what to bring. The deprecation entry itself is on the changelog examples page, in the API changelog sample.

How to use this template

  1. Write the summary before anything else

    Take the next number, set the status to Draft and write one paragraph: what changes, for whom and from when. Someone who reads nothing else should be able to say yes or no. Put the proposal in the first sentence, the way the inverted pyramid puts the news first.

  2. Show the problem with evidence

    Incidents, numbers, support tickets, costs. Without evidence, a review tends to become an argument about taste. Say what happens if nobody does anything, because doing nothing is the option every RFC competes with.

  3. Propose one thing, then argue with it

    Write the proposal as numbered statements a reviewer can accept or object to one at a time. List the alternatives, including doing nothing, and the drawbacks of your own proposal before anyone else points them out.

  4. Name the decider and a closing date

    One person or group decides; reviewers advise. Pick a comment period long enough for the busiest reviewer to read the RFC properly. Rust's final comment period lasts ten calendar days so that it covers at least five business days, a reasonable floor for many teams.

  5. Answer every comment in the log

    Copy each comment from the thread or the meeting into the comment log, with your response and its resolution: changed the RFC, answered, or not adopted and why. Reviewers who see their objection recorded are less likely to raise it again.

  6. Record the decision, then leave the text alone

    The decider sets the status and fills in the decision. After that, fix typos and add links, but if the plan changes substantially, write a new RFC that supersedes this one and link the two.

What goes in each section

SectionThe question it answersWrite it so that
SectionHeaderThe question it answersWho decides, and by when?Write it so thatAnyone can see at a glance whether comments are still open
SectionSummaryThe question it answersWhat exactly are we agreeing to?Write it so thatIt works as the whole RFC for someone who reads nothing else
SectionProblemThe question it answersWhy change anything?Write it so thatEvery claim has a number, an incident or a ticket behind it
SectionProposalThe question it answersWhat will be true afterwards?Write it so thatEach numbered line can be accepted or rejected on its own
SectionImpactThe question it answersWho has to do what, and when?Write it so thatEvery affected team appears by name, with a date
SectionAlternatives consideredThe question it answersWhat else could work?Write it so thatEach option is argued as its supporters would argue it
SectionDrawbacks and risksThe question it answersWhat does this cost?Write it so thatThe author names the cost before a reviewer does
SectionRolloutThe question it answersHow do we get there, and back?Write it so thatDates, owners and the last point where it can be undone
SectionOpen questionsThe question it answersWhat isn't settled yet?Write it so thatEach question has someone who will answer it
SectionComment logThe question it answersWhat did reviewers say, and what changed?Write it so thatEvery comment has a response and a resolution
SectionDecisionThe question it answersWhat did we decide, and why?Write it so thatSomeone who missed the discussion can follow the reasoning
The sections of the template, in order. Delete any that a small RFC doesn't need.

RFC statuses from Draft to Accepted

The status line is what turns a document into a process. Without it, reviewers can't tell whether a comment can still change anything. These statuses are a local convention, adapted from Rust's process: no standard defines them, so rename them to suit your team. The capitalized key words in a proposal are different, because RFC 2119 and RFC 8174 define what they mean.

StatusWhat it meansWho sets it
StatusDraftWhat it meansStill being written; not ready for commentsWho sets itAuthor
StatusOpen for commentsWhat it meansCirculated; comments count until the closing dateWho sets itAuthor
StatusFinal comment periodWhat it meansThe decider has proposed an outcome; last chance to objectWho sets itDecider
StatusAcceptedWhat it meansAgreed; the work can startWho sets itDecider
StatusRejectedWhat it meansTurned down, with the reasons in the decisionWho sets itDecider
StatusPostponedWhat it meansA reasonable idea at the wrong time; can be reopenedWho sets itDecider
StatusWithdrawnWhat it meansThe author pulled itWho sets itAuthor
StatusImplementedWhat it meansThe change has shippedWho sets itAuthor or the team that built it
StatusSupersededWhat it meansReplaced by a later RFC, linked in the headerWho sets itAuthor of the new RFC

Two public processes show how strict this can get. In Rust's RFC process, a team member proposes a final comment period with a disposition (merge, close or postpone), the rest of the team signs off, and the period runs ten calendar days. In the IETF's series, a published RFC never changes: later RFCs update or obsolete it, and known errors are recorded as errata.

RFC formats and samples

FormatUse it forSections
FormatOne-page RFCUse it forA decision inside one or two teamsSectionsSummary, problem, proposal, open questions, decider, closing date
FormatFull engineering RFCUse it forChanges across teams or to a public interfaceSectionsThis template
FormatProcess RFCUse it forHow people work: code review, on-call, release daysSectionsCurrent process, proposed process, a trial period and how you will judge it, who is affected
FormatOpen-source RFCUse it forProposals from contributors in a public repositorySectionsRust's template: summary, motivation, guide-level and reference-level explanations, drawbacks, rationale and alternatives, prior art, unresolved questions, future possibilities
FormatIETF RFCUse it forInternet standards and protocolsSectionsA formal series with its own format, statuses and review

The name comes from the oldest of these. RFC 1, “Host Software”, was written by Steve Crocker at UCLA in April 1969; the series is older than the IETF itself. In RFC 3, the same month, Crocker set out the conventions: a note could hold any thought or suggestion, be as short as one sentence and be timely rather than polished, to encourage the exchange of “considerably less than authoritative ideas”. An engineering RFC keeps that spirit and adds the discipline of the IETF's later practice.

Write requirements with MUST and SHOULD

Many IETF RFCs mark how binding each requirement is with key words defined in RFC 2119 (Scott Bradner, March 1997). MUST, REQUIRED and SHALL mean an absolute requirement, and MUST NOT an absolute prohibition. SHOULD and RECOMMENDED mean there may be valid reasons to do otherwise, but the full implications must be understood first. MAY and OPTIONAL mean truly optional. RFC 8174 (Barry Leiba, May 2017) added that the words carry these meanings only in capitals, so “you must” in ordinary prose stays ordinary.

The same words make an engineering RFC easier to review: MUST for the lines that make the proposal what it is, SHOULD for strong defaults with room for exceptions, MAY for options. RFC 2119 asks for them to be used with care and sparingly, and an RFC where every line says MUST leaves reviewers nothing to negotiate. The template's Proposal section has a one-line note saying the capitals follow RFC 2119 and RFC 8174; delete it if you don't use them.

“Use this template” opens a new RFC in Strokes, ready to fill in; keep each one as a numbered document in an rfcs folder. When comments arrive, save the discussion thread as a file, attach it to a chat with the Strokes Assistant and ask it to list each objection with who raised it, ready for the comment log. The responses are still yours to write.

Frequently asked questions

What is the difference between an RFC and a design doc?

A design doc explains how to build something and why that way, mostly for the engineers who will build it. An RFC asks a wider group to agree to a change, with a decider and a closing date. Many companies use the names for the same document, and an RFC can link to a design doc for the detail.

How long should an RFC comment period be?

Long enough for the busiest required reviewer to read it properly, often one to two weeks. Rust's final comment period lasts ten calendar days so that it covers at least five business days. Put the closing date in the header, and if you extend it, say so in the header too.

Can you change an RFC after it is accepted?

Fix typos and add links, but don't change the substance. Rust's process says accepted RFCs should not be substantially changed and that substantial changes need a new RFC, and a published IETF RFC never changes at all. Write a new RFC that supersedes the old one, and link the two.

Read next

Oops, you don't have Strokes yet

Install it, then press “Use this template” again.