Developer Knowledge

How to Write RFCs That Get Read

How to write RFCs that get read — a practical guide for engineers who want their technical proposals to receive genuine engagement rather than being ignored or rubber-stamped, through a document structure that makes the trade-offs legible and the decision required.

Back to blogAugust 16, 20269 min read
acwrite-rfcs-that-get-read-best-practiceswrite-rfcs-that-get-read-templatewrite-rfcs-that-get-read-tools

The RFC Problem

An RFC (Request for Comments) is a proposal document. Its purpose is to gather feedback on a technical decision before it's made — to surface objections, alternatives, and considerations that the author may not have seen, and to build shared understanding before implementation begins.

Most RFCs fail at this purpose. They fail in one of two ways:

The rubber stamp: The RFC is reviewed perfunctorily. Reviewers see it in their inbox, skim the first paragraph, and approve it because declining to engage seems easier than the conversation. The author builds the proposal; the problems the RFC process was supposed to surface appear during implementation or production.

The ignored document: The RFC is circulated and not read. No feedback comes in. The author either proceeds anyway (the RFC becomes a formality that provides the appearance of process without its substance) or waits indefinitely.

Both failure modes have the same root cause: the RFC was too long, too dense, or too poorly structured for busy engineers to engage with productively. An RFC that takes 45 minutes to read in order to have an informed opinion will not get read by the people who have 5 minutes.

Good RFCs are written for the reader, not for the author. They make the problem unmistakably clear in the first paragraph, state the proposed solution concisely, and present trade-offs in a way that tells reviewers exactly what they're being asked to decide.


What an RFC Is For (and What It's Not For)

An RFC is for: Decisions that affect multiple teams or multiple engineers. Significant architectural changes. Adoption of new technologies or major dependencies. Changes to team-wide conventions or processes. Any decision where the cost of being wrong after implementation is significantly higher than the cost of more deliberation before implementation.

An RFC is not for: Implementation details within a service. Routine technology choices that one engineer or team can make independently. Performance optimizations that don't change the public contract. Anything that can be decided in a synchronous conversation.

The RFC process exists to prevent expensive wrong decisions, not to impose process on all decisions. If the decision can be made and reversed cheaply, it doesn't need an RFC. If it can't, it probably does.


The RFC Structure That Works

An RFC that gets read has six sections in order:

1. Problem statement (required, first, short): One paragraph — ideally two to four sentences — that states the problem the RFC addresses. Not the background, not the context, not the history of how the problem arose. The problem, stated clearly, with enough specificity that the reader understands what's at stake.

Good problem statement: "Our deployment pipeline currently requires manual approval at three stages, adding an average of 4.2 hours to each deployment cycle. At our current velocity (3-4 deployments per week), this costs approximately one engineer-day per week and delays hotfixes by hours when latency is most costly."

Bad problem statement: "Our deployment pipeline has been in place since 2022 and was designed for a team of 5 engineers. Since then, the team has grown to 18 engineers and we now deploy 3-4 times per week. The original design was based on a process from [Company A] and adapted for our specific constraints. Over the past 18 months, several team members have raised concerns about the approval stages..."

The bad version makes the reader work to find the problem. The good version states it directly.

2. Proposed solution (required): What you propose to do. Specific enough that a reviewer can form an opinion — not so detailed that the RFC becomes an implementation spec. The proposed solution should be evaluable in principle before the implementation details are known.

3. Alternatives considered (required): What you considered doing instead, and why you didn't propose it. This section is often skipped or abbreviated; it's one of the most important. Without it, reviewers who have an alternative solution in mind will object to the proposal without a shared context. With it, the conversation moves to "given that we've already ruled out X because of Y, does that reasoning hold?"

Minimum: two alternatives with a one-paragraph explanation of each and the reason for not proposing them.

4. Open questions (required): The things you're not sure about. The tradeoffs you're not sure how to evaluate. The assumptions that might be wrong. The areas where you explicitly want reviewer input.

This section is the most direct invitation for engagement. A reviewer who has nothing to say about a confident proposal often has something to say about an open question. Open questions also signal intellectual honesty — the author knows the limits of their analysis.

5. Consequences (required): What changes if this proposal is adopted. What does it make easier? What does it make harder or foreclose? Who is affected (which teams, which systems)? What's the migration or transition path for existing systems?

6. Appendices / detailed design (optional, separated): The deep implementation details, diagrams, benchmarks, and research that informed the proposal. Placed at the end so readers who want depth can find it without readers who need the summary being slowed down.


The RFC Template

# RFC: [Short, descriptive title]

**Author:** [Name]  
**Date:** [Date]  
**Status:** [Draft | Under Review | Accepted | Rejected | Withdrawn]  
**Reviewers:** [Named engineers or teams whose feedback is explicitly requested]  
**Decision deadline:** [Date by which feedback is needed — specific, not "ASAP"]

---

## Problem

[1-3 paragraphs: What problem does this RFC address? 
Why does it need to be addressed now?
What is the cost or impact of not addressing it?]

---

## Proposed Solution

[2-4 paragraphs or a structured list: What do you propose to do?
Specific enough to form an opinion; not an implementation spec.
If the solution has multiple components, present them in order of importance.]

---

## Alternatives Considered

### Option A: [Short name]

[1-2 paragraphs: What this would look like + key reason not proposed]

### Option B: [Short name]

[1-2 paragraphs: What this would look like + key reason not proposed]

---

## Open Questions

1. [Question you want feedback on]
2. [Assumption you're not sure about]
3. [Trade-off where you want the team's input]

---

## Consequences

**If adopted:**
- [Positive consequence 1]
- [Positive consequence 2]
- [Negative consequence or trade-off 1]

**Migration path:**
[How does existing behavior change? What's the transition for affected systems/teams?]

**What this forecloses:**
[Are there options that become harder or impossible if this is adopted?]

---

## Appendix (optional)

[Detailed design, benchmarks, diagrams, research — for readers who want depth]

The Decision Deadline: Non-Negotiable

The single change that most improves RFC engagement is a specific decision deadline.

An RFC without a deadline can be read whenever. Reading something you can do whenever means reading it never. A specific date — "feedback requested by 2026-11-20; the decision will be made regardless of whether feedback is received" — creates urgency and makes clear that silence will be treated as acquiescence.

The deadline should be:

  • At least 5 business days after the RFC is circulated (reviewers need time)
  • No more than 10 business days (long enough to read; short enough to maintain urgency)
  • Specific: "November 20" not "two weeks" and not "ASAP"

State the consequence of no feedback: "If no objections are raised by the deadline, this proposal will be adopted." This is not aggressive; it's honest. It tells reviewers that their engagement determines the outcome.


Named Reviewers

An RFC sent to a team distribution list or a Slack channel is reviewed by no one. When review is everyone's responsibility, it's no one's.

Name the reviewers. "This RFC requests feedback specifically from @platform-team, @security-lead, and @principal-engineer." Named reviewers know they're expected to respond; unnamed reviewers know they can defer.

Named reviewers should include:

  • Engineers who will be affected by the change
  • Engineers with expertise in the domain (security, performance, infrastructure)
  • Engineers who represent teams that will need to adapt

Two to five named reviewers is sufficient for most RFCs. More than eight and you've named too many; nobody believes they need to respond.


Presenting Trade-offs, Not Conclusions

An RFC that presents a conclusion without trade-offs doesn't give reviewers anything to engage with. "We should adopt GraphQL because it's better" produces no feedback — reviewers who agree have nothing to add, and reviewers who disagree don't know what they're disagreeing with.

An RFC that presents trade-offs explicitly gives reviewers a surface to respond to: "Given that the proposed solution prioritizes developer experience at the cost of query complexity management overhead, and we've assessed that complexity management is a solvable operational problem, we're proposing GraphQL. If you disagree with that trade-off assessment, that's the place to engage."

Trade-offs to make explicit:

  • Speed vs. reliability
  • Simplicity now vs. flexibility later
  • Performance vs. developer experience
  • Team familiarity vs. technical fit
  • Short-term cost vs. long-term cost

The proposal may have a preferred direction for each trade-off. State the direction and the reasoning, and note where the reasoning might be wrong.


Length and Format

Target length: 400-800 words for the six required sections. Longer RFCs get read less thoroughly; most RFCs can be written concisely.

Formatting: Headers and bullet points over prose where the content permits. Reviewers scan before they read; headers and bullets make the scan productive. Dense paragraphs of technical analysis require sequential reading — which reviewers won't do unless the problem statement has convinced them it's worth the time.

The executive summary as first paragraph: The first paragraph of the RFC should stand alone as a summary. If someone reads only the first paragraph, they should know: what problem this addresses, what's proposed, and why now. This is not a separate "TL;DR" section — it's how the problem statement section should be written.


After the RFC: Closing the Loop

An RFC that produces feedback but no documented decision fails its purpose. After the decision deadline:

Record the decision: Add a "Decision" section to the RFC document with: what was decided, the date, and the key factors that informed the decision.

Update the status: Change the RFC status from "Under Review" to "Accepted" or "Rejected."

Close the feedback thread: In whatever channel was used for discussion, post a summary of the decision. Reviewers who engaged should know the outcome; reviewers who didn't engage but are affected should know the decision is final.

Create the ADR: If the RFC resulted in an architectural decision, write an ADR that records the decision formally. The RFC is a proposal process; the ADR is the decision record. They serve different purposes.


Worked Example: A Rate Limiting RFC

Setup: An engineering team needs to decide how to implement API rate limiting for their public API. The senior engineer writes an RFC.

# RFC: API Rate Limiting Strategy

**Author:** Yuki Chen  
**Date:** 2026-10-18  
**Status:** Under Review  
**Reviewers:** @api-team, @security-lead, @product-manager  
**Decision deadline:** 2026-10-25

---

## Problem

Our public API has no rate limiting. In the past two months, two customers 
have hit pathological usage patterns (automated polling at 10-second intervals) 
that have degraded service for other customers during peak hours. We need rate 
limiting before we expand the API's customer base in Q4.

---

## Proposed Solution

Implement token bucket rate limiting at the API gateway (Kong) with the 
following defaults:
- 1,000 requests/minute per API key
- 10,000 requests/hour per API key
- Response headers: X-RateLimit-Remaining, X-RateLimit-Reset

Limits configurable per customer by support team via Kong admin API. 
No code changes required in backend services.

---

## Alternatives Considered

### Leaky bucket at the application layer
Would give us more granular control over rate limiting logic but requires 
code changes in every service. Kong's token bucket covers our needs without 
service-level changes. Rejected for higher implementation complexity.

### Fixed window counting
Simpler than token bucket but creates burst-at-window-boundary behavior.
A customer can make 1,000 requests at 11:59 and 1,000 more at 12:00.
Token bucket smooths this. Rejected for inferior traffic shaping.

---

## Open Questions

1. Should new customers default to the same limits as existing ones, 
   or should we start with lower limits and increase on request?
2. Should we implement rate limiting before or after the Q4 API expansion?
   (I've assumed before, but there may be reasons to defer.)
3. Are there existing customers whose integrations we know will break 
   at 1,000 req/min? (Product team may know this better than I do.)

---

## Consequences

If adopted: automated polling patterns that caused September incidents 
are throttled; API stability improves for other customers.
Migration: existing customers receive 30-day advance notice with new 
response headers before enforcement begins.
Forecloses: customers who require > 1,000 req/min at sustained rates 
will need enterprise pricing discussions.

This RFC is 380 words in the main sections. It states the problem in two sentences, the proposal in one paragraph, two alternatives with reasoning, three specific open questions, and a short consequences section. It has a named deadline and named reviewers. A reviewer who disagrees with the token bucket choice knows exactly where to engage.


Key Takeaways

  1. A specific decision deadline is the single highest-leverage change: "feedback by November 20, decision regardless of whether feedback is received" converts an optional read into a time-bounded engagement.
  2. Name reviewers explicitly: a named reviewer knows they're expected to respond; an unnamed reviewer knows they can defer — the difference between these is the difference between engagement and silence.
  3. Open questions are the most direct invitation for engagement: a reviewer who has nothing to say about a confident proposal often has something to say about an explicitly uncertain question.
  4. Trade-offs over conclusions: an RFC that states trade-offs explicitly gives reviewers something to respond to; one that states conclusions without trade-offs doesn't.
  5. 400-800 words for the required sections: reviewers won't commit to reading more before they know whether the problem statement justifies the investment; make the problem compelling in the first paragraph.

Conclusion

An RFC that gets read is short, structured for scanning before sequential reading, specific about what decision is required and by when, honest about trade-offs, and explicit about open questions. The rubber stamp and the ignored document are failures of communication, not failures of content — they happen when the RFC asks busy engineers to do too much work to form an opinion. The RFC that reduces that work, by making the problem clear in a paragraph, the trade-offs explicit in a list, and the open questions unmistakable, is the RFC that gets the engagement it was asking for.

Try WebSnips free — save RFC templates, past proposal discussions, and technical reference materials with your own annotations, tag by decision domain and team, and build the organized technical decision library that makes every new RFC more informed.

Keep reading

More WebSnips articles that pair well with this topic.

Developer KnowledgeAugust 17, 202610 min read

How to Build a Knowledge Base for a Dev Team

How to build a knowledge base for a dev team — a practical guide for engineering teams who want a shared knowledge system that engineers actually use, that stays current as the team grows, and that reduces the time engineers spend re-answering the same questions.

acbuild-a-knowledge-base-for-a-dev-team-best-practicesbuild-a-knowledge-base-for-a-dev-team-templatebuild-a-knowledge-base-for-a-dev-team-tools
Read article
Developer KnowledgeAugust 17, 20269 min read

How to Document a Microservices Architecture

How to document a microservices architecture — a practical guide for engineering teams navigating service sprawl, where the challenge is not documenting individual services but making the relationships, contracts, and operational behavior of a distributed system legible.

acdocument-a-microservices-architecture-best-practicesdocument-a-microservices-architecture-templatedocument-a-microservices-architecture-tools
Read article
Developer KnowledgeAugust 17, 20268 min read

How to Keep a Changelog Developers Trust

How to keep a changelog developers trust — a practical guide for engineering teams who want a CHANGELOG.md that consumers of their API or library actually read and rely on, rather than a dump of commit messages that obscures more than it reveals.

ackeep-a-changelog-developers-trust-best-practiceskeep-a-changelog-developers-trust-templatekeep-a-changelog-developers-trust-tools
Read article
Developer KnowledgeAugust 17, 20269 min read

How to Save and Organize Design Docs

How to save and organize design docs — a practical guide for engineers and engineering teams who want their design documents to remain findable, useful, and connected to the decisions they documented, rather than accumulating in an untended archive.

acsave-and-organize-design-docs-best-practicessave-and-organize-design-docs-templatesave-and-organize-design-docs-tools
Read article
Developer KnowledgeAugust 17, 20268 min read

How to Take Notes During Code Review

How to take notes during code review — a practical guide for engineers who want to get more from code review than the immediate feedback loop: building a personal reference of patterns, anti-patterns, and architectural decisions accumulated across months of reviews.

actake-notes-during-code-review-best-practicestake-notes-during-code-review-templatetake-notes-during-code-review-tools
Read article
Developer KnowledgeAugust 17, 20269 min read

How to Track Tech-Debt Decisions

How to track tech-debt decisions — a practical guide for engineering teams who want to manage their technical debt as intentional trade-offs rather than accumulated accidents, with a tracking system that makes debt visible, prioritizable, and repayable.

actrack-tech-debt-decisions-best-practicestrack-tech-debt-decisions-templatetrack-tech-debt-decisions-tools
Read article