A design document that arrives after the work has started is a status report wearing a costume. Everyone comments on wording, nobody challenges the approach, and the one person who would have spotted the problem with the data model reads it three weeks later when changing course is expensive.
The purpose of writing one is to get disagreement early, while it is still cheap. That framing determines everything about how it should be written: it is an argument requesting scrutiny, not a record announcing a plan.
Lead with the problem and the alternatives
Open with the problem, stated concretely enough that someone could disagree that it is a problem. Then the constraints — the traffic, the deadline, the team, the systems you cannot change — because a reviewer who does not know your constraints will propose approaches you already ruled out.
Then the alternatives, seriously considered. A document with one option and a paragraph dismissing two strawmen is not asking for input; it is asking for approval. Reviewers engage with real trade-offs, and the quality of the objections you get is a direct function of how honestly you presented the options.
- Problem, in concrete terms with numbers where you have them.
- Constraints that genuinely bound the solution space.
- Two or three real options with honest trade-offs, including the cost of doing nothing.
- The recommendation and why — the part most people put first and which means little without the above.
- What you are explicitly not solving. Scope creep in review is the most common way these stall.
- Open questions, stated plainly. A document with no uncertainty is either trivial or dishonest.
Two sections earn their place more than most: how you will know it worked, and how it will be rolled out and reverted. The first forces a measurable claim rather than a vague improvement. The second surfaces the migration and compatibility problems that otherwise appear in week three, and it is where most of the real difficulty in a design usually hides.
# Replacing the nightly export with incremental sync
**Status:** Draft — review by Fri 4 Sep | **Author:** @me | **Reviewers:** @a @b
## Problem
The nightly export takes 4h12m (was 1h when built), and finishes after the
customer's 06:00 SLA 3 days in 10. Growth puts it past 6h by Q1.
## Constraints
- Customer systems poll a file; changing their side needs 90 days' notice.
- No new datastore this quarter (platform team is at capacity).
## Options
1. **Parallelise the existing export.** ~2h. Cheapest, buys ~9 months.
2. **CDC into an incremental file.** ~6 weeks. Solves it structurally; adds a
connector to operate and a replication slot to monitor.
3. **Do nothing.** Misses SLA daily by Q1. Contractual penalty applies.
## Recommendation
Option 1 now, option 2 next quarter with the 90-day notice starting immediately.
## Success
Export completes before 05:00 on 20 consecutive days.
## Rollout / reversal
Run both in parallel for 2 weeks, compare checksums, cut over by flag.
## Not solving
The schema of the exported file. Separate decision, ADR-016.
## Open questions
- Does parallelising breach the source database's connection budget at 03:00?You are not writing to be approved. You are writing so that the person who can see the flaw has a chance to say so before it is expensive.
And frequently the right answer is not to write one. A change contained within one team, reversible in an afternoon, with no interface other teams depend on, does not need a document — it needs a pull request. Reserve the format for decisions that are expensive to reverse or that other people will have to live with, which in most teams is a handful a quarter rather than one per project.