Software engineering · For beginners

Write It Before You Build It: A Practical Guide to Design Docs

Khairul Alam·October 2026·~15 min read
Design docsSoftware designTeamworkTemplates

Most expensive mistakes in software are not typos. They are the wrong thing built well, or the right thing built in a way that nobody else agreed with. A design doc is a short document you write before you build, so those mistakes show up while they still cost a paragraph instead of a month. This post covers what goes in one, a complete example, a template you can copy, the benefits, the costs, and the cases where you should not write one.

The whole post in 60 seconds
  • A design doc explains what you plan to build, why, and how, and what else you considered.
  • Its main job is to get feedback while change is still cheap.
  • Good ones are short, name their goals and non-goals, and compare real alternatives.
  • They cost time, and they go stale. Do not write one for small, easy-to-undo work.
  • Ask the other teams the change affects: security, operations, support, product and more. Each sees a risk you cannot.
  • A one-page template and a worked example are below.
Contents
  1. What a design doc is
  2. How a design doc lives
  3. What goes inside
  4. A worked example
  5. Reviews from other teams
  6. A template you can copy
  7. What makes one good
  8. Benefits
  9. Costs and common failures
  10. When not to write one
  11. Takeaways and glossary

1. What a design doc is

A design doc is a written plan for a change, shared with the people who will be affected by it before the work starts. It is not a specification that predicts every detail, and it is not documentation of finished code. It is a thinking tool: writing forces you to find the gaps, and sharing it lets other people find the ones you missed.

Analogy. An architect draws plans before the builders pour concrete. Moving a wall on paper takes an eraser. Moving it after the walls are up takes a demolition crew. A design doc is the paper stage.

It is usually a page or three, written in plain language. If you can explain the idea to a new teammate without opening the code, you are close to a good doc.

2. How a design doc lives

The document is not a one-off. It moves through a few simple stages, and the most valuable ones are the middle two: review and decision.

Idea Draft Review Decide Build Update the doc when reality changes the plan
Review is where the value is. The loop at the bottom keeps the doc from going stale.

3. What goes inside

Different teams use different headings, but the useful ones are always the same. Each answers a question a reader will have.

SectionQuestion it answers
ContextWhat is the situation, and why now?
GoalsWhat must be true when this is done?
Non-goalsWhat are we deliberately not doing?
ProposalWhat exactly will we build, and how will the pieces fit?
AlternativesWhat else did we consider, and why not those?
RisksWhat could go wrong, and how will we notice?
RolloutHow do we ship it safely and undo it if needed?
Open questionsWhat do we still not know?
ReviewsWho looked at it, what did they say, and what changed because of it?

The two sections people skip: Non-goals prevent scope creep by writing down what you will not do. Alternatives prove you chose rather than defaulted. Reviewers read these two first.

4. A worked example

Here is a small but realistic design doc, shortened to fit. The scenario: an online shop sends the order receipt email during checkout. The numbers are made up for illustration.

Design doc: send order receipts asynchronously

Author: Aiko  ·  Reviewers: Product, Security, Operations, Support, QA, Finance, Data  ·  Status: In review

Context

Checkout calls the email provider and waits for it before showing the “order placed” page. When the provider is slow, customers wait, and some press the button twice. Last month, 3% of checkouts took longer than 8 seconds, and every one of them was an email delay.

Goals

Non-goals

Proposal

When an order is saved, we also save a small “send receipt” job in the same database transaction. A background worker reads pending jobs, sends the email, and marks the job done. Failed jobs retry with growing delays, up to 24 hours, then raise an alert.

Checkout Databaseorder + job Worker Emailprovider 1. save2. poll3. send Checkout returns after step 1. Email problems no longer reach the customer.
Saving the job together with the order means a job cannot be lost if the app crashes in between.

Alternatives considered

OptionWhy not
Keep it synchronous, add a shorter timeoutFewer slow checkouts, but a timeout means a lost receipt with no retry.
Fire and forget in a new threadSimple, but a crash or restart silently drops emails.
Managed message queue serviceThe most robust, but a new system to run for about 200 orders a day. Revisit if volume grows tenfold.

Risks

Rollout

Ship behind a flag. Enable for 10% of orders for two days, compare receipt delivery rates, then 100%. To roll back, turn the flag off and checkout returns to the old path.

Open questions

Notice what the doc does not contain: no class names, no full code, no framework tutorial. It gives reviewers enough to disagree with the decision, and that is the point.

5. Reviews from other teams

Engineers reading an engineering doc will mostly find engineering problems. But the receipt change also touches customer data, on-call duty, the support desk, the budget and the team’s schedule. Each of those groups sees a different risk, and only they can see it. Asking them early is much cheaper than hearing from them after launch.

Design docone shared page ProductRight problem? ArchitectFits the big picture? SecurityWho sees the data? ManagersTime, people, risk? OperationsWhat pages us? QA and testHow do we test it? SupportCan we explain it? Finance, dataCost? Measurable?
Eight common reviewers ask eight different questions.

Who to ask, and what they look for

StakeholderTypically checks
Product or business ownerThe problem is real, the goals match what customers need, the scope is worth the cost.
Architect or tech leadThe design fits the wider system, reuses existing building blocks, follows agreed standards, and does not make future changes harder.
Engineering peersThe design fits the codebase, is testable, and does not create hidden maintenance work.
Teams that use your API or dataNothing they depend on changes without warning. This is the compatibility check.
Security and privacyWhat personal data is stored, who can read it, how long it is kept, and what an attacker could do.
Operations or SREMonitoring, alerts, capacity, runbooks, and how the change fails.
QA and testThat the failure cases can be reproduced and checked before release.
Designers (UX)Anything the customer sees is clear, consistent and accessible.
Customer supportThat support can see what happened to a customer’s request and explain it.
Data and analyticsThat the success measures can be collected, and that existing reports do not silently break.
FinanceRunning cost, vendor fees, and any change to billing.
Engineering or project managersEffort, timing, staffing, dependencies on other teams, and whether the risk is acceptable for the schedule.
Legal or complianceRegulations, contracts and data-retention rules, where they apply.

You do not need all of them every time. Pick the groups whose work the change could affect. Asking someone who is not affected adds delay and no insight.

What the reviews looked like for the receipts doc

Here is a realistic set of comments on the example from section 4, and what the author did with each one. Notice that some comments changed the design, some were declined with a reason, and one fixed an open question.

ReviewerCommentOutcome
Security“The job table stores customer email addresses. Who can read it, and how long do we keep it?”Accepted. Only the worker can read it. Completed jobs are deleted after 30 days. Added to the Risks section.
Architect“The platform already has a standard retry helper. Can the worker use it instead of custom retry code?”Accepted. The worker now uses the platform helper, so the retry delays come from shared code. Proposal section updated.
Operations“An alert is good. Who gets it, and what do they do when it fires?”Accepted. Alert goes to the on-call rotation. Added a short runbook and a queue-age dashboard.
Support“Customers ask ‘where is my receipt?’ Can we see whether it was sent?”Accepted. Added a read-only job status view for the support tool. Also answered the open question: yes, show “receipt on its way” on the confirmation page.
Product“A receipt a day late is not useful for many orders. Is 24 hours right?”Accepted. Retry limit reduced to 6 hours, then alert. Open question closed.
QA“How do we test when the provider is down?”Accepted. Added a test plan using a fake provider that fails on demand.
Finance“Do retries increase what we pay the email provider?”Answered, no change. The provider bills per accepted message, and the duplicate guard prevents double sends. Noted in the doc.
Data“Can we measure the time from order to receipt?”Accepted. Added a delivery-delay metric to the success checks.
Engineering manager“This is about two weeks for one engineer, and on-call needs a short briefing. Can it land before the holiday sales freeze?”Accepted. Added a timeline: build in two weeks, a 10% rollout in week three, and full rollout only after the freeze ends.
Mobile team (uses the order API)“Does the order response change?”Answered. No. Added a Compatibility line to say so.
Engineering peer“Use a managed message queue instead of a database table.”Declined, with reason. Already listed under Alternatives: too heavy for about 200 orders a day. Revisit if volume grows tenfold.

When reviewers disagree

They will. Support may want receipts retried for as long as possible, while Product wants them dropped after a few hours. Do not average the opinions. Write both down, explain the trade-off, and let the person who owns the decision choose. Then record the outcome in the decision log so nobody reopens it by accident:

## Decision log
- 2026-10-12: Retry receipts for 6 hours, then alert a person.
  Support asked for 24 hours; Product argued a late receipt is not
  useful. Decided by the Product owner. Revisit if support tickets
  about missing receipts rise.

How to run a review well

6. A template you can copy

Paste this into your wiki, a markdown file in the repository, or a shared document. Delete sections that do not apply, but think twice before deleting Non-goals and Alternatives.

# Design doc: <short, specific title>

Author:     <name>
Reviewers:  <names>
Status:     Draft | In review | Approved | Superseded
Last edit:  <date>

## Summary
Two or three sentences. What are we doing and why?

## Context
What is the situation today? What problem hurts, for whom, how much?
Include numbers or examples if you have them.

## Goals
- What must be true when this is done? (testable if possible)

## Non-goals
- What this project deliberately will not do.

## Proposal
How it works, in plain words. Add one diagram.
Cover data, interfaces, and how the main pieces talk to each other.

## Alternatives considered
| Option | Pros | Cons | Why not |
|--------|------|------|---------|

## Risks and mitigations
- Risk: ...   Mitigation: ...

## Security, privacy, and cost (if relevant)
Who can access what? What personal data is involved? What does it cost to run?

## Rollout and rollback
How do we release it gradually? How do we undo it?

## How we will know it worked
Metrics, alerts, or checks, and the target for each.

## Open questions
- Things nobody knows yet, and who will find out.

## Reviews and sign-off
| Team | Reviewer | Status (pending / approved / concerns) | Notes |
|------|----------|----------------------------------------|-------|

## Decision log
- <date>: <what was decided and why>

Scale the template to the work. A two-day change may need only Summary, Proposal and Risks, half a page in total. A change touching many teams may need every section.

7. What makes one good

8. Benefits

BenefitWhat it looks like
Cheaper mistakesA wrong assumption is fixed in a paragraph, not after a month of code.
Clearer thinkingWriting exposes vague parts. If you cannot explain a step, you do not understand it yet.
Shared understandingEveryone starts from the same picture, so fewer surprises in code review.
Better decisionsMore eyes catch security, cost, and operations concerns early.
A memory for the teamNew joiners learn why things are built this way, which code alone cannot tell them.
Easier to say no (or yes)Debates focus on a page, not on whoever argues the loudest.
Asynchronous workPeople in other time zones can contribute without joining a call.

9. Costs and common failures

Design docs are not free, and bad ones are worse than none. Watch for these:

10. When not to write one

Match the weight of the paper to the weight of the decision. Two questions help: how hard is this to undo? and how many people does it affect?

Just do itsmall, reversible Short notea message ora PR description Design docdays of work,several people Formal reviewmany teams,hard to undo,security or data More effort and risk →
Do not climb higher than the work needs.
Skip the doc when…Do this instead
The change is small and easy to undo (a bug fix, a rename, a copy tweak)Explain it in the PR description.
The problem is well known and the solution is obvious to everyonePost a two-line message and move on.
You do not yet know what is possibleBuild a quick throwaway prototype, then write up what you learned.
It is a personal project or a one-day experimentKeep a few notes for yourself.
An emergency fix is needed nowFix first, write the short post-incident note after.
The doc would only record a decision already finalWrite a short decision record, not a design doc.

Rule of thumb: write one when the work will take more than a few days, touches other people’s code or data, is hard to reverse, or you find yourself explaining it more than twice.

11. Takeaways and glossary

TermIn plain words
Design docA written plan for a change, shared for feedback before building.
Goal / non-goalWhat the project must achieve, and what it deliberately will not do.
AlternativeAnother way to solve the same problem, with the reason it was not chosen.
RFC“Request for comments”: a design doc shared widely, often across teams.
Decision recordA short note capturing one decision and why it was made.
StakeholderAnyone whose work or customers are affected by the change.
Sign-offA reviewer’s recorded approval that their concerns are addressed.
Blocking commentA review comment that must be resolved before the work can start.
Rollout / rollbackReleasing a change gradually, and the plan for undoing it.
Feature flagA switch that turns a new behaviour on or off without a new release.
PrototypeA quick, disposable build used to answer a question.
← Back to all writing