Team Lead Mindset

Design Docs, RFCs and Writing Things Down

What real projects (Rust, Kubernetes, Python) put in a design doc, status words, a simple review process, when not to write one, and tips for clear writing.

Lesson 0515 min read#design-docs#rfc#writing

On this page

  1. Words used in this lesson
  2. Why write it down
  3. What real projects put in the document
  4. A simple process that works
  5. Writing tips from the lists
  6. Interview questions
  7. Key takeaways
  8. What's next

In one line: a design doc (or RFC) is a short written plan that you share before you build. It makes your thinking visible, lets others find holes while they are cheap to fix, and leaves a record of why. Big projects such as Rust, Python and Kubernetes all work this way.

In Lesson 1 and 2 you saw small decision notes. This lesson is about the bigger written plan: what goes in it, how real projects structure it, how to get feedback without endless arguments, and when not to write one.

Start with Lesson 0 for the six-step answer shape. A design doc is that same shape, written down.

Everything here is common practice and opinion. Teams differ. Use the ideas, not the exact words, and always use your own true examples.

What I checked. I read these directly (raw text on GitHub): the Rust RFC template and process, PEP 1 (how Python decides), the Kubernetes enhancement (KEP) template, and the "when to write a decision record" advice in architecture-decision-record. The advice about writing well comes from what the charlax/professional-programming list says about its articles; I did not open those articles. "Design Docs at Google" and the "Lightweight RFC Process" from Apache are recommended in the lists but I did not read them. The small-team template at the end is my own mix of the three real ones.

Words used in this lesson

  • A design doc is a short document that explains a plan: the problem, the proposal, the other options and the risks. You write it before the work.
  • An RFC (Request for Comments) is a design doc that is shared for comments from a wider group, with a decision at the end.
  • A KEP is Kubernetes' name for an enhancement proposal. A PEP is Python's name. They are RFCs with their own rules.
  • Goals and non-goals. Goals are what the plan must achieve. Non-goals are things you will not do, written down so the discussion stays focused.
  • Alternatives are the other options you considered, and why you did not choose them.
  • Prior art is how other teams or projects solved the same problem.
  • Rollout and rollback are how you release the change in steps, and how you go back if it goes wrong.

Why write it down

The long reading lists that many engineers use agree on a few simple reasons (I summarise what the lists say about each article):

  • Writing is cheaper than building. One article in the list says a few days of design writing can save weeks of wasted implementation, because writing exposes a flawed design early.
  • A written memo forces clearer thinking than slides. Another says slides hide how ideas connect to each other; sentences do not.
  • A document culture helps everyone join in. An article about Amazon's document culture says written documents reduce bias and avoid audio and screen-sharing problems in meetings.
  • People review at their own time. A reader in another time zone can think before they answer.

The Python PEP rules give another reason, in their own words about what a good PEP has: it records why the choice was made and which ideas were rejected, so the same arguments do not repeat every year.

What real projects put in the document

Three public templates, side by side. They are different sizes, but you can see the same bones.

IdeaRust RFCKubernetes KEPPython PEP
What and whySummary, MotivationSummary, MotivationAbstract, Motivation (a weak motivation can get a PEP rejected)
What is in and out of scope(in Motivation and Unresolved questions)Goals, Non-GoalsSpecification
The proposalGuide-level explanation (teach it as if it already exists), Reference-level explanation (the technical design)Proposal, Design DetailsSpecification, Rationale
RisksDrawbacksRisks and Mitigations, Drawbacks(in Rationale)
Other optionsRationale and alternatives, Prior artAlternativesRationale, Rejected Ideas
How to prove it works(in the design)Test Plan, Graduation Criteria, Production Readiness Review (observable, scalable, supportable, can it be rolled back?)Reference implementation
What is still openUnresolved questions, Future possibilities(in sections above)Open issues

Two things stand out. Every one of them has a place for why not (drawbacks, alternatives, rejected ideas). And the biggest project (Kubernetes) adds a production readiness check: can we see it, scale it, support it and roll it back?

A small-team design doc (my own mix)

For one team, one page is often enough. Use these headings and keep each part short:

MD
# Title: the decision, not the problemStatus: draft | in review | accepted | rejected | withdrawn | replaced by <link>Owner: <name>     Reviewers: <names>     Decide by: <date>## Summary            (3 sentences)## Problem            (who is hurt, how much, how do we know)## Goals / Non-goals  (what must be true / what we will NOT do)## Proposal           (how it works, with one small example)## Alternatives       (at least two, and why not)## Risks              (what could go wrong, how we reduce each)## Rollout / rollback (steps, flag or switch, how to go back)## Test and monitoring plan (how will we know it works)## Open questions

The status words come from Python's PEP process: Draft, Accepted, Rejected, Withdrawn (the author dropped it or chose another), Deferred (stalled, can come back), Final (done), and Superseded (replaced by a newer one). Using clear status words stops people asking "is this still true?".

A simple process that works

  1. Talk first. Have a short chat with one or two people before you write. The Rust process says the same: discuss the idea informally before you write the RFC.
  2. Write a short draft and name one owner and the reviewers.
  3. Set a date. Give people a fixed time to comment (Rust's "final comment period" is ten calendar days, see Lesson 2).
  4. Answer every comment, even with "noted, not now". Change the document, not only the chat.
  5. Decide. Python's PEP rules say one body has the final say (the Steering Council, who can delegate a single PEP to a person). In a team, say who decides before you start. You do not need everyone to agree, but write down the reasons.
  6. Record the outcome and the rejected ideas. Link it from the pull requests.

Do not write a design doc for everything. The decision-record advice says to skip it when the decision is tiny, limited in scope, risk or cost, made by one developer, already covered by a standard, or temporary (a workaround or proof of concept). A design doc is for decisions that are big or hard to undo.

Writing tips from the lists

The reading list has a small writing section. In simple words:

  • Cut words. George Orwell's six rules (cut unnecessary words, prefer the active voice, avoid jargon) apply to design docs too.
  • Be specific. One article says swap general words for specific ones: "slow" becomes "p95 of 2.3 s".
  • Short sentences, active voice. This is the advice of Google's "Technical Writing One" course, as the list describes it.
  • Start with the answer. Put the decision and what you need from the reader at the top.
  • Show an example. The Rust template asks you to teach the idea "as if it were already part of the language". A tiny example makes a plan real.

Interview questions

When do you write a design doc? (Must know)

When the change is big, hard to undo, or touches other teams: a new service, a database change, a public API, a new library for the whole app. I skip it for small, local, easy-to-change work, where a good pull request description is enough. A simple test: "If I am wrong, how much will it cost to fix?" If the answer is "a lot", I write it down first.

What goes into a good design doc? (Must know)

A clear problem (who is hurt and how we know), goals and non-goals, the proposal with a small example, at least two alternatives and why not, the risks and how to reduce them, a rollout and rollback plan, a way to measure success, and open questions. Real projects (Rust, Kubernetes, Python) all include a place for "why not", because the reasons for rejecting an idea are as useful as the idea itself.

How do you get feedback without endless debate? (Senior signal)

I name an owner and a decider before I start, share the draft with a date for comments, and I answer every comment in the document. I split comments into "must fix before we start" and "can be decided later". If a thread goes round in circles, I take it to a short call and bring the outcome back into the document. When the date comes I decide, write down the reasons, and move on. People accept a decision they disagree with more easily when they can see their point was heard and recorded.

What is the difference between a design doc, an RFC and a decision record? (Must know)

A design doc is the plan before the work. An RFC is a design doc that goes through a shared review process with a decision at the end. A decision record (ADR) is a very short note that records one decision, its context and its consequences, often written after (or from) the design discussion. The design doc says how we think; the ADR keeps what we decided and why for later readers. In a small team, one document can do both jobs.

Someone raises a big objection after the decision. What do you do? (Trap)

First I listen: is this new information or a point we already weighed? If it is new and important, we reopen the decision, and I say so openly and update the document. If it is a point already in the "rejected ideas" section, I show where we discussed it and thank them. The Rust process works the same way: if major new arguments appear during the last comment period, the process stops and the proposal goes back to development; if not, the decision stands. I do not treat "the doc is approved" as a wall, and I do not reopen every decision for every complaint.

How do you write a good status update or message? (Must know)

I start with the answer or the ask: "We are on track. I need a decision on X by Friday." Then the two or three facts that support it, then the risk, then the next step. I use short sentences, active voice, and numbers instead of "a lot" or "soon". I read it once as if I knew nothing about the project. If I cannot tell what the reader should do, I rewrite the top.

Key takeaways

  • Write the plan before the work when the change is big or hard to undo. Skip it for small, local, reversible work.
  • A good doc has: problem, goals and non-goals, proposal, alternatives, risks, rollout and rollback, how you will measure success, open questions.
  • Always include "why not" (drawbacks, alternatives, rejected ideas). It stops the same debate from returning.
  • Use clear status words: draft, accepted, rejected, withdrawn, replaced.
  • Name an owner and a decider, set a date for comments, answer every comment, then decide.
  • Write short, specific, active sentences, with the answer first.
  • This is common practice and opinion. Adapt it to your team.

What's next

Next: Technical debt, quality and the rewrite trap, Lesson 6. Practise: take one decision from your last project and write the one-page doc as if you were starting today. Notice how hard it is to write the "alternatives" and "risks" parts honestly.

Published by Jainik · Last updated · How these lessons are made

Keep learning

Part of the study guide

Related series