Writing RFC and ADR Documents in English
How to write technically precise RFCs and Architecture Decision Records using RFC 2119 obligation language, formal structure vocabulary, and professional prose.
An RFC (Request for Comments) and an ADR (Architecture Decision Record) are two of the most consequential documents an engineer writes. They are read by people you may never meet, quoted in future decisions, and sometimes treated as binding contracts between teams. Getting the English right is not merely a matter of style — the wrong word choice can introduce genuine ambiguity that causes real problems months later.
This guide covers the specific language patterns that make RFCs and ADRs professional, unambiguous, and useful.
RFC 2119: The Obligation Language Standard
When engineers write specifications and design documents, they often need to distinguish between what a system must do, what it should do, and what it may do. RFC 2119, published by the Internet Engineering Task Force in 1997, defines a precise vocabulary for this. Using it correctly signals technical professionalism and eliminates ambiguity.
The key terms are:
| Term | Meaning | Usage |
|---|---|---|
| MUST / REQUIRED / SHALL | Absolute requirement — no flexibility | ”The service MUST validate the JWT signature before processing the request.” |
| MUST NOT / SHALL NOT | Absolute prohibition | ”The client MUST NOT retry a request with a 400 response code.” |
| SHOULD / RECOMMENDED | Strong preference; deviations allowed with justification | ”Implementations SHOULD use exponential backoff when retrying.” |
| SHOULD NOT / NOT RECOMMENDED | Strong preference against; allowed with justification | ”The API SHOULD NOT return internal stack traces to the caller.” |
| MAY / OPTIONAL | Genuinely optional — acceptable either way | ”Clients MAY cache responses for up to 60 seconds.” |
Convention: Write these keywords in uppercase when you intend the RFC 2119 meaning. This is a signal to the reader that you are using the terms technically, not colloquially.
What to avoid: Using “should” (lowercase) when you mean “must” creates hidden requirements. “The service should validate input” sounds like a recommendation. “The service MUST validate input” is a requirement. These have completely different implications for implementation and audits.
RFC Structure and Vocabulary
A well-structured RFC contains predictable sections. Here is the language pattern for each.
Title and Summary
The title should be concrete: “Proposal: Migrate Rate Limiting to a Shared Sidecar” is better than “Rate Limiting Improvements.”
The abstract or summary should answer one question in two to four sentences: what are you proposing, and why?
- “This document proposes replacing the per-service rate-limiting implementations with a shared Envoy sidecar proxy. The motivation is to eliminate duplicated logic across 14 services, reduce configuration drift, and enable centralised rate-limit policy management.”
Motivation
This section answers “why?”. Use clear causal language:
- “The motivation for this change is…”
- “The current approach has the following drawbacks…”
- “This proposal is driven by…”
- “The problem we are solving is…”
Example: “The motivation for this change is the inconsistent enforcement of rate limits across services. Three services currently have no rate limiting at all, and the implementations that exist use different algorithms and configuration schemas, making policy auditing impractical.”
Proposal / Design
This is the technical core. Use:
- “The proposed solution is to…”
- “Under this design, [component] will [behaviour].”
- “The flow for a typical request would be as follows…”
- “This approach differs from the current implementation in that…”
Be specific about system behaviour, not just intent. “The sidecar will intercept all inbound HTTP requests” is better than “the sidecar will handle requests.”
Alternatives Considered
This section is important and often written poorly. The purpose is to show you thought rigorously, not to dismiss alternatives quickly.
- “We considered three alternatives to this approach.”
- “Alternative A: [description]. This was rejected because…”
- “Alternative B would have been simpler to implement, but it does not address the audit requirement.”
- “We also evaluated [tool/approach] but found that…”
Avoid: “Alternative A was considered but not chosen.” Give the reader enough to understand the reasoning.
Open Questions / Out of Scope
- “The following questions remain open and will be resolved before implementation…”
- “This proposal does not address [topic] — that will be covered in a separate RFC.”
- “The following are explicitly out of scope for this proposal…”
ADR Structure and Vocabulary
Architecture Decision Records are shorter and more focused than RFCs. They document a single architectural decision: what was decided, why, and what the consequences are. The standard format has five sections.
1. Status
One of: Proposed, Accepted, Deprecated, Superseded by ADR-042.
- “Status: Accepted (2026-04-12)”
- “Status: Superseded by ADR-007: PostgreSQL Migration”
2. Context
Describe the situation that forced a decision. Use neutral, factual language:
- “The application currently stores session data in Redis. As we scale to multiple regions, the need for a consistent session store across regions has become a blocker for the geo-distribution project.”
- “We need to choose a message broker for the new event-driven architecture. This decision affects all services that produce or consume events.”
3. Decision
State the decision clearly and directly. Start with the decision, then justify it:
- “We will adopt Apache Kafka as the primary message broker.”
- “We have decided to use PostgreSQL for the primary datastore rather than a document database.”
- “The team has agreed to follow the Hexagonal Architecture pattern for all new services.”
Avoid passive constructions that obscure agency: “It was decided that Kafka would be used” is weaker than “We will use Kafka.” In an ADR, clarity about who decided what matters.
4. Consequences
This is where many ADRs are too thin. A good consequences section covers both positive and negative outcomes:
- “This decision results in stronger consistency guarantees for session data at the cost of increased operational complexity.”
- “Teams will need to learn Kafka’s producer/consumer model. We will provide a shared client library to reduce the learning curve.”
- “This choice creates a dependency on Kafka’s availability. We accept this tradeoff because [reason].”
- “Future services will not need to make this decision independently — the standard is established.”
5. Rationale (optional but recommended)
Explain why the alternatives were insufficient:
- “We evaluated RabbitMQ and AWS SQS. RabbitMQ offers sufficient throughput but lacks the log-based replay semantics we require for the audit trail. SQS would create vendor lock-in that conflicts with our multi-cloud strategy.”
Tone and Register
Both RFCs and ADRs should be written in formal but not bureaucratic English. Some guidelines:
Use active voice for decisions and requirements:
- “The service validates the token” rather than “The token is validated by the service.”
Use present simple for behaviours:
- “The load balancer distributes traffic across healthy instances.”
- “Each pod exposes a
/healthzendpoint.”
Use future tense for proposed changes:
- “The new architecture will route all traffic through the API gateway.”
- “Teams will be responsible for maintaining their own ADR directories.”
Avoid hedging in requirement statements. If you write “the service might need to validate the token”, you have created ambiguity. Say “the service MUST validate the token” or explain the conditions under which validation is optional.
Common Mistakes
Mixing SHOULD and MUST: This is the single most consequential mistake. If reviewers treat a SHOULD as a MUST, they will over-engineer. If they treat a MUST as a SHOULD, they will under-implement.
Passive-heavy motivation sections: “It has been observed that…” and “It has been noted that…” pad word count without adding clarity. Say what you observed and who observed it.
Alternatives that are not really alternatives: “We could do nothing” is rarely a genuine alternative. List options that were seriously evaluated, not strawmen.
Consequences that are only positive: Real architectural decisions have tradeoffs. An ADR with only positive consequences looks like it has not been thought through.
Writing good RFCs and ADRs is a skill that compounds. Each document you write forces you to think precisely, and that precision — both technical and linguistic — transfers to every other form of written communication in your engineering career.