- Introduction
- Types and Purposes of Technical Documents: RFC, ADR, Design Doc
- RFC Writing Guide and Templates
- ADR Writing Guide and Templates
- Design Doc Structure and Examples
- Effective English Expressions and Patterns
- Review Process Design
- Global Team Communication Strategy
- Common Mistakes and Corrections
- Operation Checklist
- Failure Cases and Improvements
- References

Introduction
A software engineer spends only 30 to 40 percent of the working day writing code. The rest goes to design, discussion, review, and documentation. On a global team in particular, the ability to leave a technical decision behind as an English document becomes the sharpest differentiator in a career. Companies like Google, Meta, Uber, and Spotify have settled into a culture of writing an RFC (Request for Comments), an ADR (Architecture Decision Record), or a Design Doc first, and winning the team's agreement, before any code is written.
Korean developers hit two difficulties in that process. First, they cannot cleanly separate what each of RFC, ADR, and Design Doc is for. All three sit under the label "technical document," which leaves it vague which one to write when. Second, they are not fluent in the sentence patterns English uses to develop a technical argument, compare alternatives, and justify a decision.
This article separates the structure and purpose of the three documents cleanly and gives you an English template and practical phrasing for each. Not translation tips, but a concrete guide to writing technical documents that actually land on a global team.
Types and Purposes of Technical Documents: RFC, ADR, Design Doc
The Core Difference Between the Three
RFCs, ADRs, and Design Docs differ in purpose and in lifecycle. Mix them and the document loses focus, leaving reviewers unsure what they are supposed to give feedback on.
| Item | RFC | ADR | Design Doc |
|---|---|---|---|
| Purpose | Propose and reach agreement | Record a decision and its reasoning | Design and plan the implementation |
| When written | Before a large change | Right after the decision | Before implementation starts |
| Lifespan | Archived after approval or rejection | Kept permanently | Referenced after implementation |
| Length | 2-10 pages | 1-2 pages | 5-20 pages |
| Audience | The whole team, or the organization | Current and future team members | The engineers doing the work |
| Central question | "Should we make this change?" | "Why did we decide this?" | "How will we build it?" |
| Status values | Draft, In Review, Accepted, Rejected | Proposed, Accepted, Deprecated, Superseded | Draft, In Review, Approved, Implemented |
| Alternatives analysis | Required (three or more recommended) | Required (the alternatives considered) | Optional (for the major design choices) |
Which Document to Write, and When
Use the decision tree below.
[Is the change broad in scope?]
├── Yes: it affects several teams → write an RFC
│ └── Once the RFC is approved → write a Design Doc
│ └── For each major decision → write an ADR
└── No: contained inside one team
├── Is it an architectural decision?
│ └── Yes → write an ADR
└── Do you need an implementation plan?
└── Yes → write a Design Doc (lightweight version)
The core principles are these. An RFC is a proposal seeking agreement, an ADR is the permanent record of a decision, and a Design Doc is the blueprint for the implementation. One project can need all three, and the most common flow is to start with an RFC, write a Design Doc once it is approved, and leave the major decisions made along the way as ADRs.
RFC Writing Guide and Templates
The Structure of an RFC
An RFC — Request for Comments — is exactly what the name says: a document asking for opinions. It comes from the IETF internet standards RFCs, but in software engineering it means "a technical proposal." Uber writes thousands of RFCs a year; Google calls the same thing a "Design Doc" but follows essentially the same process.
The RFC Template in English
# RFC-0042: Migrate User Service to Event-Driven Architecture
| Field | Value |
| ------------- | ----------------------------- |
| **Status** | In Review |
| **Authors** | Jane Kim (jane@example.com) |
| **Created** | 2026-03-01 |
| **Updated** | 2026-03-05 |
| **Reviewers** | @backend-team, @platform-team |
## Summary
A one-paragraph summary of the proposal. This should be concise enough
that someone can understand the core idea in 30 seconds.
> We propose migrating the User Service from a synchronous REST-based
> architecture to an event-driven architecture using Apache Kafka.
> This change aims to reduce inter-service coupling, improve fault
> tolerance, and enable real-time data propagation to downstream
> consumers.
## Motivation
Why are we doing this? What problem does it solve? Include data
and metrics wherever possible.
- Current synchronous calls between User Service and 7 downstream
services create cascading failures. In Q4 2025, we experienced
12 incidents directly caused by this coupling.
- Average response time for user profile updates is 1,200ms due
to synchronous fan-out to notification, analytics, and billing
services.
- The current architecture cannot support the projected 10x growth
in user events expected by Q3 2026.
## Proposed Solution
### High-Level Design
Describe the proposed solution in enough detail for reviewers to
understand the approach without reading the implementation details.
### Detailed Design
Include diagrams, API contracts, data models, and workflow
descriptions as needed.
## Alternatives Considered
### Alternative 1: Async HTTP with Retry Queue
Description of the alternative and why it was not chosen.
**Pros:**
- Minimal code changes required
- Team is already familiar with HTTP-based patterns
**Cons:**
- Does not fundamentally solve the coupling problem
- Retry storms can overwhelm downstream services
### Alternative 2: gRPC Streaming
Description and trade-off analysis.
## Migration Plan
How will we roll this out? Include phases, timelines, and rollback
procedures.
1. **Phase 1 (Week 1-2):** Set up Kafka cluster and deploy
to staging environment.
2. **Phase 2 (Week 3-4):** Dual-write to both REST and Kafka
for the notification service.
3. **Phase 3 (Week 5-6):** Migrate remaining consumers one
by one with feature flags.
4. **Phase 4 (Week 7-8):** Remove synchronous endpoints after
validation period.
### Rollback Plan
If critical issues are detected, we can revert to synchronous
calls by disabling the feature flag. Kafka messages will be
retained for 7 days, allowing replay after fix deployment.
## Risks and Mitigations
| Risk | Impact | Likelihood | Mitigation |
| -------------------------- | ------ | ---------- | --------------------------------------------- |
| Message ordering issues | High | Medium | Use partition keys based on user ID |
| Consumer lag during peak | Medium | High | Auto-scaling consumer groups + alerting |
| Data loss during migration | High | Low | Dual-write validation with reconciliation job |
## Open Questions
- Should we use Kafka Connect or custom consumers for the
analytics pipeline?
- What is the acceptable message delivery latency SLA?
## References
- [Event-Driven Architecture at Uber](https://example.com)
- [Kafka Best Practices](https://example.com)
Core Principles for Writing an RFC
1. The summary must be readable in 30 seconds. Whether it is an executive or an engineer from another team, they should be able to read the summary alone and judge whether this RFC is relevant to them.
2. The motivation must contain data. "The current architecture is complex" is an opinion, not evidence. "We had 12 incidents in Q4 2025, with a mean time to recovery of 47 minutes" is evidence.
3. Present at least two alternatives. Put forward a single option with no alternatives and you have no answer to "why not do it another way?" State the pros and cons of each alternative, then explain logically why the proposal is the better one.
4. Do not be afraid of open questions. You do not have to hold every answer. Leave the unresolved questions on the page explicitly and reviewers will focus there and give you constructive feedback.
ADR Writing Guide and Templates
What an ADR Is
An ADR (Architecture Decision Record) is a short document capturing the context, the reasoning, and the consequences of an architectural decision. Since Michael Nygard proposed it in 2011, Spotify, GitHub, GOV.UK, and many others have adopted it as standard practice. Where an RFC focuses on the proposal, an ADR focuses on the decision itself.
The core value of an ADR is letting a future team member understand the context of a past decision. When someone who joined six months later asks "why did we pick PostgreSQL over MongoDB?", an ADR conveys the constraints and the discussion of that moment exactly.
The ADR Template in English
# ADR-0015: Use PostgreSQL as the Primary Database
| Field | Value |
| ------------- | ------------------------------ |
| **Status** | Accepted |
| **Date** | 2026-03-04 |
| **Deciders** | Jane Kim, Alex Park, Sarah Lee |
| **Consulted** | Database Team, Security Team |
## Context
We need to select a primary database for the new Order Management
Service. The service will handle approximately 50,000 orders per
day initially, with projected growth to 500,000 orders per day
within 18 months.
Key requirements:
- ACID transactions for order state management
- Complex queries for reporting and analytics
- JSON support for flexible product metadata
- Strong ecosystem for monitoring and tooling
The team has production experience with both PostgreSQL and MongoDB.
Our existing infrastructure runs PostgreSQL 15 for three other
services.
## Decision
We will use **PostgreSQL 17** as the primary database for the
Order Management Service.
## Rationale
1. **ACID compliance**: Order processing requires strict
transactional guarantees. PostgreSQL's MVCC provides
this without application-level workarounds.
2. **Operational familiarity**: The team already operates
three PostgreSQL instances. Adding MongoDB would
increase operational overhead and require new runbooks.
3. **JSON support**: PostgreSQL's JSONB type with GIN
indexing satisfies the flexible metadata requirement
without sacrificing query performance.
4. **Cost**: Our existing database infrastructure and
tooling (pgBouncer, pg_stat_statements, Patroni)
can be reused.
## Alternatives Considered
### MongoDB
- **Pros:** Native JSON document model, flexible schema,
horizontal scaling with sharding
- **Cons:** Eventual consistency by default requires careful
configuration for order processing, additional operational
overhead, separate monitoring stack needed
- **Rejected because:** The operational cost of maintaining
two database ecosystems outweighs the benefits of native
document storage.
### Amazon DynamoDB
- **Pros:** Fully managed, auto-scaling, single-digit
millisecond latency
- **Cons:** Limited query flexibility, complex data modeling
for relational data, vendor lock-in
- **Rejected because:** The reporting requirements demand
complex JOINs and aggregations that DynamoDB does not
natively support.
## Consequences
### Positive
- Consistent operational practices across all services
- Reduced time-to-production due to existing expertise
- Full SQL support for future analytics requirements
### Negative
- Vertical scaling limits may require sharding strategy
if growth exceeds projections
- JSONB queries are less intuitive than MongoDB's query
language for deeply nested documents
### Risks
- If order volume exceeds 500K/day significantly ahead
of schedule, we may need to implement read replicas
or table partitioning earlier than planned.
## Related Decisions
- ADR-0012: Event sourcing for order state transitions
- ADR-0014: Use Patroni for PostgreSQL HA
Core Principles for Writing an ADR
1. One ADR holds exactly one decision. Put "database choice and caching strategy" into one ADR and searching for or referencing either becomes hard later. Split by decision.
2. Record the constraints of the moment faithfully in Context. Over time the team size, the tech stack, and the schedule pressure of that period all disappear from memory. You need to be able to answer the future question "why did we pick this instead of the optimal option?"
3. Record the negative consequences honestly too. Every decision carries a trade-off. Hide the downsides and the document loses credibility — and nobody is prepared when the same problem comes back.
4. Manage the status strictly. An ADR's status is one of Proposed, Accepted, Deprecated, or Superseded. When a new decision replaces an old one, change the old ADR's status to "Superseded by ADR-XXXX" and reference the old ADR from the new one.
Design Doc Structure and Examples
The Role of a Design Doc
A Design Doc is more concrete than an RFC and broader than an ADR. It holds the detailed blueprint for how you will build it, and it is the tool for getting a design review before the code review. At Google every significant project starts with a Design Doc, and that culture is regarded as the core mechanism that makes people think before they write code.
The Design Doc Template in English (Core Structure)
# Design Doc: Real-Time Notification Pipeline
| Field | Value |
| ---------------- | ---------------------------------------------- |
| **Authors** | Jane Kim, Alex Park |
| **Status** | Approved |
| **Last Updated** | 2026-03-05 |
| **Approvers** | Sarah Lee (Tech Lead), Mike Chen (Staff Eng.) |
| **Related RFCs** | RFC-0042 (Event-Driven Architecture Migration) |
## 1. Overview
### 1.1 Objective
Build a real-time notification pipeline that delivers push
notifications, emails, and in-app messages within 5 seconds
of trigger events, supporting 100K notifications per minute
at peak load.
### 1.2 Background
Following the approval of RFC-0042, we are migrating from
synchronous notification delivery to an event-driven model.
Currently, notifications are sent synchronously during API
request processing, adding 200-800ms to response times and
creating tight coupling between the User Service and the
Notification Service.
### 1.3 Goals and Non-Goals
**Goals:**
- Deliver notifications within 5 seconds of trigger events
- Support push, email, and in-app notification channels
- Handle 100K notifications/min at peak without degradation
- Provide per-user notification preferences and opt-out
**Non-Goals:**
- SMS delivery (planned for Phase 2)
- Marketing campaign notifications (separate system)
- Real-time chat functionality
## 2. High-Level Design
[Architecture diagram description]
The pipeline consists of four main components:
1. **Event Ingestion Layer**: Consumes events from Kafka
topics published by upstream services.
2. **Routing Engine**: Determines which channels to use
based on event type and user preferences.
3. **Channel Adapters**: Deliver notifications via push
(FCM/APNs), email (SES), and in-app (WebSocket).
4. **Feedback Loop**: Tracks delivery status and handles
retries for failed deliveries.
## 3. Detailed Design
### 3.1 Data Model
[Detailed schema definitions, API contracts, and
sequence diagrams go here]
### 3.2 API Contracts
[Endpoint specifications with request/response examples]
### 3.3 Error Handling and Retry Strategy
- Transient failures: Exponential backoff with jitter,
max 3 retries
- Permanent failures: Dead letter queue with alerting
- Channel-specific: FCM token refresh on
InvalidRegistration errors
## 4. Scalability and Performance
### 4.1 Load Estimates
| Metric | Current | Target (6 months) |
| ------------------------ | ------- | ----------------- |
| Notifications/min (avg) | 10K | 50K |
| Notifications/min (peak) | 30K | 100K |
| End-to-end latency (p99) | 3s | 5s |
### 4.2 Scaling Strategy
- Kafka consumer groups with auto-scaling based on
consumer lag metric
- Horizontal pod autoscaler targeting 70% CPU utilization
- Email sending rate limiter to stay within SES quotas
## 5. Security and Privacy
- All notification content encrypted at rest (AES-256)
- PII fields (email, device tokens) stored in separate
encrypted columns
- GDPR compliance: user data deletion propagated within
72 hours
## 6. Testing Strategy
- Unit tests for routing logic (target: 90% coverage)
- Integration tests with embedded Kafka
- Load test simulating 150K notifications/min
- Chaos testing: Kafka broker failure, SES outage
## 7. Rollout Plan
| Phase | Timeline | Scope | Rollback Trigger |
| ----- | -------- | -------------------- | ----------------- |
| 1 | Week 1-2 | Internal dogfooding | Any P0 bug |
| 2 | Week 3 | 5% of users (canary) | Error rate > 0.5% |
| 3 | Week 4 | 50% of users | Error rate > 0.1% |
| 4 | Week 5 | 100% of users | Error rate > 0.1% |
## 8. Open Questions and Risks
- How should we handle notification deduplication across
channels?
- What is the retention policy for notification history?
## 9. Appendix
- Link to prototype: [URL]
- Performance benchmark results: [URL]
- Related ADRs: ADR-0015, ADR-0017
Core Principles for Writing a Design Doc
1. State the non-goals. Being clear about what you will not do prevents scope creep and cuts down on reviewers asking about features that were never in play.
2. Give concrete numbers. Not "handles heavy traffic" but "delivers 100K notifications per minute within 5 seconds" — a measurable target. That target becomes the criterion for your design decisions, and the yardstick for judging success later.
3. Put rollback triggers in the rollout plan. A phased deployment plan on its own is not enough. At each phase, state numerically what going wrong means and when you roll back.
Effective English Expressions and Patterns
English Expressions That Recur in Technical Documents
A technical document is not literature. Clear and direct phrasing wins. Below are patterns you can use immediately, sorted by situation.
| Situation | Recommended | Avoid |
|---|---|---|
| Making a proposal | "We propose..." / "This RFC proposes..." | "I think maybe we should..." |
| Presenting evidence | "Based on our analysis of..." / "Data from Q4 shows..." | "I feel like..." / "In my opinion..." |
| Explaining an alternative | "We considered X but rejected it because..." | "X is bad because..." |
| Explaining a trade-off | "The trade-off is..." / "This approach sacrifices X for Y." | "The downside is kind of..." |
| Recording a decision | "We decided to use X." / "The team agreed on X." | "X was chosen." (by whom?) |
| Something unresolved | "This remains an open question." / "We need further investigation on..." | "I don't know about this part." |
| Bounding the scope | "This is out of scope for this document." | "We won't bother with..." |
| Naming a constraint | "Given the constraint that..." / "Due to the requirement for..." | "Because of stuff..." |
Formal vs. Informal Tone
A technical document should sit near the formal end, but the right register is "professional" rather than academic.
| Informal (avoid) | Professional (recommended) | Too formal (unnecessary) |
|---|---|---|
| "This is gonna fix the bug." | "This change resolves the race condition." | "Herein we present a remediation for the aforementioned defect." |
| "We can just throw in a cache." | "We propose adding a caching layer to reduce latency." | "It is hereby proposed that a caching mechanism be introduced." |
| "The old system is pretty slow." | "The current system shows p99 latency of 2.3 seconds." | "The extant system exhibits suboptimal temporal performance characteristics." |
| "Let's use Kafka or whatever." | "We recommend Kafka for its proven reliability at our scale." | "After exhaustive deliberation, the committee recommends the adoption of Kafka." |
Useful Sentence Patterns
Explaining the background of a proposal:
"As our user base has grown from 1M to 10M monthly active users,
the current architecture has shown signs of strain, particularly
in [specific area]."
"Over the past quarter, we observed [metric] degradation,
which correlates with [root cause]."
Justifying a design decision:
"We chose X over Y primarily because [reason 1]. Additionally,
[reason 2] and [reason 3] supported this decision."
"While Y offers [advantage], the operational complexity
it introduces outweighs the benefits for our current scale."
Naming a risk:
"The primary risk of this approach is [risk]. We plan to
mitigate this by [mitigation strategy]."
"If [condition] occurs, we will [fallback plan]."
Review Process Design
The Review Workflow
When the review process for technical documents is not systematic, document quality swings wildly and reviews either drag on forever or end as a formality. Below is the review workflow we recommend.
[Step 1: Self-Review]
The author self-checks against the checklist (1 day)
|
[Step 2: Peer Review]
One or two teammates review it (2-3 days)
|
[Step 3: Stakeholder Review]
The tech lead of each affected team reviews (3-5 days)
|
[Step 4: Final Approval]
The approver, a staff or principal engineer, makes the call (1-2 days)
|
[Step 5: Archive]
Update the final status and store it in the repository
The PR Description Template
When technical documents live in a Git repository, the PR itself is a communication document. Below is the template to use when you open a PR for an RFC or an ADR.
## Summary
This PR introduces RFC-0042 proposing the migration of User
Service to an event-driven architecture.
## Type of Document
- [x] RFC (Request for Comments)
- [ ] ADR (Architecture Decision Record)
- [ ] Design Doc
## Key Decisions Requested
1. Should we use Kafka or Pulsar for the event bus?
2. Is the proposed 8-week migration timeline realistic?
3. Are there additional risks we have not considered?
## Reviewers
- @backend-team: Technical feasibility
- @platform-team: Infrastructure implications
- @security-team: Security review of event payload design
## Review Deadline
Please provide feedback by **2026-03-10**. If no objections are
raised by the deadline, this RFC will be considered accepted.
## How to Review
- Focus on the **Alternatives Considered** section first.
- Check if the **Risks and Mitigations** are comprehensive.
- Comment inline on specific sections if possible.
How to Write Review Comments
Useful patterns for leaving English comments as a reviewer.
[Asking a question]
"Have we considered the impact on [X]?"
"What happens if [edge case]?"
"Could you clarify the rationale for choosing X over Y?"
[Suggesting an improvement]
"Consider adding a section on [topic] to address [concern]."
"It might be worth including metrics from [source] to
strengthen the motivation."
"Suggestion (non-blocking): Mentioning the rollback SLA
would help on-call engineers."
[Expressing agreement]
"LGTM - the trade-off analysis is thorough."
"+1 on the proposed approach. The phased rollout plan
is well-structured."
[Raising a concern]
"I have concerns about [specific aspect]. Specifically, [detail]."
"Blocking: The security implications of [X] need to be
addressed before we proceed."
Global Team Communication Strategy
Asynchronous First
A global team spans time zones, so asynchronous communication is the default. Technical documents are the core tool of that mode, and one well-written document replaces several meetings.
Principles of an asynchronous document:
- Self-contained: the reader should get the full context from the document alone. "As we discussed in the last meeting" does not belong in it.
- Explicit timeline: state the review deadline. Write "Please review by March 10, 2026," not "As soon as possible."
- Decision log: when discussion runs asynchronously the conclusions scatter easily. Summarize the decisions at the top of the document and keep a timeline of the discussion at the bottom.
Phrasing That Accounts for Cultural Difference
On a global team, the balance between direct and indirect phrasing matters.
[Disagreeing - avoid the literal translation from Korean]
Avoid: "I disagree."
(so direct it can read as conflict)
Avoid: "That might not be the best approach, maybe..."
(so indirect the point gets ignored)
Use: "I see the merit of this approach. However, I have
a concern about [specific issue]. Have we considered
[alternative]?"
[Agreeing and adding to the point]
Use: "Building on Alex's point, I think we should also
consider [additional factor]."
[When you are not certain]
Use: "I'm not fully sure about this, but my initial
read is that [opinion]. I'd appreciate others'
input on this."
The Decision Matrix
Using a decision matrix to compare alternatives keeps the discussion structured.
## Decision Matrix: Message Queue Selection
Scoring: 1 (Poor) to 5 (Excellent)
Weight: Importance multiplier
| Criteria | Weight | Kafka | RabbitMQ | Amazon SQS |
| ---------------------- | ------ | ------ | -------- | ---------- |
| Throughput | 5 | 5 (25) | 3 (15) | 4 (20) |
| Operational complexity | 4 | 2 (8) | 3 (12) | 5 (20) |
| Team familiarity | 3 | 4 (12) | 2 (6) | 3 (9) |
| Cost at scale | 3 | 4 (12) | 4 (12) | 2 (6) |
| Ecosystem/tooling | 2 | 5 (10) | 3 (6) | 4 (8) |
| **Total** | | **67** | **51** | **63** |
**Recommendation:** Kafka scores highest due to superior
throughput and strong ecosystem support, despite higher
operational complexity. The team's existing Kafka experience
(score: 4) mitigates the operational overhead.
Common Mistakes and Corrections
Writing Mistakes Korean Developers Make Most Often
1. Dropping the subject
Korean drops the subject constantly, but an English technical document needs it stated.
Wrong: "Need to migrate the database before deployment."
Right: "The team needs to migrate the database before deployment."
Right: "We need to migrate the database before deployment."
2. Missing articles (a/the)
A missing article hurts readability badly in a technical document.
Wrong: "System sends notification to user."
Right: "The system sends a notification to the user."
Wrong: "We propose using cache to reduce latency."
Right: "We propose using a cache to reduce latency."
3. Overusing the passive
The passive is natural in some places, but the default is the active voice.
Passive: "The configuration is loaded by the service at startup."
Active: "The service loads the configuration at startup."
Passive: "It was decided that Kafka would be used."
Active: "The team decided to use Kafka."
4. Ambiguous pronouns
Vague: "When the service calls the API, it returns an error."
(unclear whether it is the service or the API)
Clear: "When the service calls the API, the API returns an error."
5. Overusing "etc."
Vague: "The system handles errors, retries, etc."
Clear: "The system handles errors, retries, and circuit breaking."
"etc." is what you write when listing the actual items feels like too much work. In a technical document, name every item, or use "such as" to mark it as an example.
Operation Checklist
RFC Checklist
[ ] Is the summary three sentences or fewer?
[ ] Does the motivation contain quantitative data?
[ ] Are at least two alternatives analyzed?
[ ] Does each alternative state its pros and cons?
[ ] Is the migration or rollout plan written out in phases?
[ ] Is there a rollback plan?
[ ] Is there a Risks and Mitigations section?
[ ] Are the open questions collected?
[ ] Are the reviewers named and a review deadline set?
[ ] Has it been through a grammar and spelling check (Grammarly or similar)?
ADR Checklist
[ ] Does this ADR hold exactly one decision?
[ ] Does the context explain the constraints of the moment adequately?
[ ] Is the decision stated clearly in a single sentence?
[ ] Are the alternatives considered, and the reason each was rejected, recorded?
[ ] Do the consequences cover both the positive and the negative?
[ ] Is the status (Proposed/Accepted/Deprecated/Superseded) correct?
[ ] Are the related ADRs referenced?
[ ] Is the numbering consistent with the existing ADRs?
Design Doc Checklist
[ ] Are goals and non-goals clearly separated?
[ ] Are the performance targets given as concrete numbers?
[ ] Does the high-level design include an architecture diagram?
[ ] Is the API contract defined?
[ ] Is the error handling strategy described?
[ ] Are security and privacy considerations included?
[ ] Is the testing strategy concrete?
[ ] Does the rollout plan state a rollback trigger for each phase?
[ ] Are the related RFCs and ADRs referenced?
[ ] Are the approvers named?
Document Management Checklist
[ ] Are the documents version-controlled in a Git repository?
[ ] Is the file naming convention consistent (for example RFC-NNNN, ADR-NNNN)?
[ ] Is there a document index or catalog, and is it maintained?
[ ] Are documents that no longer apply marked Deprecated?
[ ] Is there a recurring documentation review on the calendar (quarterly is recommended)?
Failure Cases and Improvements
Case 1: A Large Migration Started Without an RFC
The situation: a team moving from a monolith to microservices skipped the RFC and went straight to code. Three months in, disagreement over the criteria for splitting services surfaced, and 30 percent of the code already written had to be rewritten.
Root cause: implementation proceeded on each person's own reading, with no agreement on service boundaries. An RFC would have forced explicit agreement on the split criteria and the communication patterns before any code was written.
The fix:
- Any change touching two or more services requires an RFC
- The RFC must include a clear service boundary diagram and the API contracts
- Establish a policy that implementation does not start before the RFC is approved
Case 2: The Recurring "Why Did We Do It This Way?" Argument, With No ADR
The situation: a newly joined senior engineer asked why Kafka had not been used instead of the message queue (RabbitMQ) chosen two years earlier. Everyone involved in that decision had left, and nobody could explain the reasoning. In the end the team spent a month re-evaluating Kafka against RabbitMQ, and the analysis confirmed the original choice had been right. That month was completely wasted.
Root cause: the context and reasoning of the architectural decision were never recorded. Fragments survived in Slack threads and meeting notes, but there was no organized document.
The fix:
- Establish a culture of writing an ADR for every architectural decision
- Keep the ADRs alongside the code, in the repository's
/docs/adr/directory - Include a "key ADRs" list in the onboarding documentation
Case 3: A Design Doc That Drifted Away From the Code
The situation: implementation started from a Design Doc approved six months earlier, but the design changed several times along the way and the document was never updated once. A new team member tried to understand the code by reading the Design Doc, and the gap between document and implementation made things worse rather than better.
Root cause: the Design Doc was treated as write-once. There was no process for updating it when the design changed mid-implementation.
The fix:
- Add a "Last Updated" field to the Design Doc and update it on every significant change
- Add "consistency with the Design Doc" to the code review checklist
- Add an "Implementation Notes" section after implementation to record what changed in the design
- Put a warning banner at the top of any Design Doc that no longer applies
> WARNING: This design doc was written in March 2026 and has
> not been updated since. The actual implementation may differ
> significantly. Refer to the codebase and ADR-0023 for the
> current architecture.
Case 4: A Review Delayed by Poor English
The situation: an RFC written by a Korean engineer had grammar errors and unclear phrasing, and reviewers burned excessive time simply working out what it said. More than ten "What does this sentence mean?" comments piled up, and the actual technical review slipped by over two weeks.
Root cause: the document was submitted with no self-check on the quality of the writing. The technical content was excellent, but it did not carry.
The fix:
- Make an English proofreading tool such as Grammarly or LanguageTool mandatory
- Ask a colleague fluent in English for a 15-minute pre-review before submitting
- Introduce a team-level "writing buddy" scheme to support non-native engineers
- Collect the expressions you use often into an internal team glossary
References
- RFCs and Design Docs - The Pragmatic Engineer - Gergely Orosz on the difference between RFCs and Design Docs, with real company examples
- Software Engineering RFC and Design Doc Culture - The Pragmatic Engineer - a concrete methodology for introducing an RFC and Design Doc culture
- When Should I Write an Architecture Decision Record? - Spotify Engineering - Spotify's criteria for writing an ADR, and their experience with it
- ADRs and RFCs: Differences and When to Use Which - Candost - a guide that separates ADRs and RFCs cleanly
- Documenting Design Decisions Using RFCs and ADRs - Bruno Scheufler - how to combine RFCs and ADRs to record design decisions systematically
- Google Developer Documentation Style Guide - the de facto standard style guide for writing technical English
- Architectural Decision Records - ADR GitHub Organization - ADR templates and tooling