Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Design Documents, RFCs, and ADRs

The act of writing forces you to think. A design document is the cheapest way to find out you’re wrong.

1. What Are Design Documents?

Design documents capture technical decisions before implementation. They exist to:

  • Force clear thinking before writing code
  • Enable peer review of architecture
  • Create a record for future engineers
  • Catch flawed assumptions early

Types of Design Documents

TypeScopeOwnerExamples
Design DocFeature or systemTech lead / engineerGoogle-style 1-pagers, Amazon 6-pagers
RFC (Request for Comments)Broad change, often cross-teamAuthor + communityRust RFCs, Python PEPs
ADR (Architecture Decision Record)Single architectural decisionAny engineerKubernetes ADRs

2. When to Write One

Write OneDon’t Bother
New system or serviceBug fixes
Cross-team dependency changesTrivial refactors
Database schema migrationInternal implementation details
API design for external consumersAdding a utility function
Changing an established patternOne-off scripts
Anything that costs > 2 weeks of work

Rule of thumb: if the cost of being wrong exceeds the cost of writing the doc, write it.

3. Structure of a Good Design Doc

Google-Style Template

1. Title and Authors
2. TL;DR (2-3 sentences)
3. Background and Motivation
4. Goals and Non-Goals
5. Proposed Design
   - Architecture diagram
   - Data model
   - API surface
   - Key algorithms
6. Alternatives Considered
7. Testing Plan
8. Monitoring and Observability
9. Rollout Plan
10. Open Questions

Goals and Non-Goals (Critical Section)

Explicitly stating what you’re not doing prevents scope creep and misaligned reviews.

## Goals
- Support paginated listing of orders with consistent ordering
- Handle 10,000 QPS with p99 < 100ms

## Non-Goals
- Real-time order updates (use WebSocket service instead)
- Admin-facing UI (separate project)
- Migrating legacy order tables

Alternatives Considered

This section demonstrates you’ve explored the design space:

## Alternatives Considered

### Option A: Event sourcing
- **Pros:** Full audit trail, temporal queries
- **Cons:** Complexity, replay cost, team unfamiliarity
- **Rejected:** Complexity doesn't justify benefit for read-heavy workload

### Option B: CQRS with separate read store
- **Pros:** Optimized reads, independent scaling
- **Cons:** Eventual consistency, operational overhead
- **Rejected:** Our SLA requires strong consistency

4. RFC Process

RFCs are formal proposals for significant changes, widely used in open-source and large organizations.

Lifecycle

Draft → Review → Final → Implemented → Archived
StageWhat HappensDuration
DraftAuthor writes the RFC, gathers initial feedbackDays to weeks
Review PeriodCommunity reviews, comments, proposes changes1-4 weeks
Final Comment Period (FCP)Last call for objections3-10 days
Accepted / RejectedMaintainer decides
ImplementedCode is written per the accepted RFCWeeks to months

Notable RFC Systems

OrganizationFormatExamples
Rustrfcs/ repo, markdown with merge processasync/await, non-lexical lifetimes
PythonPEPs (Python Enhancement Proposals)PEP 484 (type hints), PEP 572 (walrus operator)
IETFNumbered RFC documentsHTTP/1.1 (RFC 7231), TCP (RFC 793)
EthereumEIPsEIP-1559 (fee market change)

5. Architecture Decision Records (ADRs)

ADRs capture individual architectural decisions — one decision per record. They are lightweight, timestamped, and immutable once accepted.

ADR Format (Michael Nygard’s template)

# ADR-001: Use PostgreSQL as Primary Database

## Status
Accepted

## Context
We need a relational database for transactional workloads.
Options: MySQL, PostgreSQL, CockroachDB.

## Decision
We will use PostgreSQL 15 as our primary database.

## Consequences
- Positive: JSONB support, advanced indexing, strong community
- Negative: No horizontal sharding built-in (need Citus)
- Neutral: Team has PostgreSQL experience

ADR vs Design Doc

AspectADRDesign Doc
ScopeOne decisionFull system/feature
SizeShort (paragraphs)Long (pages)
MutabilityImmutable once recordedCan be revised before approval
WhenAny time a decision is madeBefore building something significant
NumberMany (one per decision)One per project/feature

6. Common Pitfalls

PitfallFix
Writing the doc after the codeEnforce doc-first culture; block PRs without approved design
Vague problem statementQuantify: “p99 latency is 2s” not “it’s slow”
No diagramInclude an ASCII or C4 diagram — a picture is worth 1000 words
Ignoring non-goalsAlways include non-goals to prevent scope creep
No alternativesShows you haven’t thought critically — always list 2-3 options
Stale ADRsKeep an ADR index; mark superseded decisions

Interview Questions

  1. When should you write a design document? For any non-trivial feature: new services, API changes, database migrations, cross-team dependencies. The cost of being wrong should exceed the cost of writing the doc. Skip for bug fixes, trivial changes, and prototypes.

  2. What is the most important section of a design doc? Goals and non-goals — they define scope and prevent scope creep. Without explicit non-goals, reviewers push for features outside the project’s scope, and implementation bloats.

  3. What is the difference between an RFC and a design doc? A design doc is for internal team decisions. An RFC is a formal proposal meant for broader review, often across an organization or community, with a structured review lifecycle.

  4. What is an ADR? How is it different from a design doc? An Architecture Decision Record captures a single architectural decision permanently. It’s short, immutable, and focused. A design doc covers an entire feature/system with multiple decisions. Projects accumulate many ADRs over time.

  5. How do you handle a disagreement during design review? First, clarify if the disagreement is about goals or approach. If goals, escalate to stakeholders. If approach, prototype both options with benchmarks. Fall back to ADR: document the decision, the dissenting opinion, and move forward — you can always revisit.

  6. What makes a good alternatives section? Each alternative should include: what it is, pros, cons, and why it was rejected. The rejected option should sound reasonable — if it sounds stupid, you haven’t represented it fairly.

  7. How do you keep design docs from becoming stale? Store them in version control alongside code. Link ADRs to the commits that implement them. During onboarding, review recent docs. Mark outdated ones as superseded, never delete.