Effective Design Doc
Source: How to Write an Effective Software Design Document by Michael Lynch (from Refactoring English)
Companion Example: Little Moments Design Doc
A good design doc saves months or years of engineering rework. It forces you to think through critical decisions before writing code and coordinates architectural consensus across teammates and partner teams.
1. The Core Filter: What’s the Cost of Being Wrong?
Not every detail belongs in a design document. If you specify everything, you have effectively written the implementation.
- High Cost of Being Wrong (1-Way Doors): Hard-to-reverse architectural choices—data persistence models, core languages/frameworks, security boundaries, public API contracts, inter-service protocols. Belongs in the design doc.
- Low Cost of Being Wrong (2-Way Doors): Easily reversible decisions—button labels, whether a list loads 25 or 50 items at a time, local helper functions. Keep out of the design doc.
2. When Should You Write a Design Doc?
Ask yourself these diagnostic questions:
- Will multiple engineers coordinate work to implement the system?
- Will the project take more than 3 months of full-time development?
- Will the implementation run in production for several years?
- Does the project involve cross-team collaboration?
- Are the project goals and requirements ambiguous?
- Are there catastrophic risks (security flaws, data loss, legal/compliance violations) that can be mitigated at design time?
Rule of thumb: If you answer "yes" to any question, a design doc is worth the effort. If you answer "yes" to two or more, it is essential.
3. Key Components of a Design Doc
You don't need every section for every doc—pick the subset that matches your project's scope and risk profile.
Foundations
- Title: Short, distinctive, and evocative (e.g., RecencyBank instead of generic or obscure project code names).
- Metadata: Author, authoritative URL (shortlink), creation date, and explicit approvers with sign-off dates.
- Objective: A single-sentence summary of the project’s purpose in plain, stakeholder-friendly language.
- Background: Answers why now, the underlying business/technical pain point, and previous attempts. Must make sense to a teammate reading without verbal introduction.
- Related Documents: Links to PRDs, test plans, functional specs, related architecture docs, or previous iterations.
Scope & Product Behavior
- Goals: High-level statements of user or business impact (e.g., “Minimize deployment outages” rather than “Install Kubernetes”).
- Non-Goals: Explicit anti-scope. Clarifies what reviewers might mistakenly assume is included.
- Scenarios: Concrete step-by-step walkthroughs of how a user or calling system interacts with the solution.
- Diagrams: System architecture, data flow, sequence, or network topologies. Use editable, reproducible formats (Mermaid, Excalidraw, D2).
- Glossary: Defines domain-specific or internal organizational jargon.
Technical Contract
- Constraints: Hard environmental limits (budget, hardware architecture like RISC-V, regulatory limits).
- Interfaces: API signatures, CLI flags, Go interfaces, Protobuf definitions, or data schemas showing interaction points.
- Dependencies & Infrastructure: Required third-party libraries, services, language choices, and hosting infrastructure—focusing on components that are difficult to swap later.
Production Readiness & Governance
- SLOs (Service Level Objectives): Concrete, measurable targets for uptime/availability, latency percentiles (p50, p95, p99), and throughput.
- Monitoring & Alerting: Exact triggers that page on-call engineers (e.g., p95 latency > 3s, CPU > 90% for 2 minutes).
- Security: Threat modeling, attack surface identification, and trust boundaries where data crosses privilege zones.
- Privacy: Sensitive user data retention, access governance, and encryption (in transit and at rest).
- Legal Considerations: Licensing (open source compatibility) and compliance with contractual or statutory obligations.
- Logging: What gets logged, log retention periods, log levels, and sanitization of PII/credentials.
Execution & History
- Timeline / Milestones: Serial, incremental deliverables with visible artifacts (e.g., dummy UI, test environment deployment, production rollout).
- Open Issues: Unresolved architectural dilemmas. For each entry, state:
- What is the problem?
- What are the viable options?
- What is the immediate next step / decision owner?
- Resolved Issues: Once decided, capture the final decision and rationale, then move from Open to Resolved for historical context.
- Alternatives Considered: Document strong rejected options and the concrete rationale why they were not chosen.
4. Driving Through Review
- Share Early: Get directional buy-in before polishing every detail.
- Focus Feedback: Guide reviewers to focus on architectural risks, blind spots, and interfaces rather than stylistic nitpicks.
- Aggressively Resolve Comments: Clarify misunderstandings directly in the document text, make decisions on open issues, and avoid perpetual comment debates.