<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Design-Docs on VividMap Blog</title><link>https://blog.vividmap.io/tags/design-docs/</link><description>Recent content in Design-Docs on VividMap Blog</description><image><title>VividMap Blog</title><url>https://blog.vividmap.io/og-image.png</url><link>https://blog.vividmap.io/og-image.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 29 Apr 2026 20:03:52 -0600</lastBuildDate><atom:link href="https://blog.vividmap.io/tags/design-docs/index.xml" rel="self" type="application/rss+xml"/><item><title>How to Write a Technical Design Document</title><link>https://blog.vividmap.io/posts/how-to-write-a-technical-design-document/</link><pubDate>Mon, 03 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.vividmap.io/posts/how-to-write-a-technical-design-document/</guid><description>Most technical design documents fail before they&amp;#39;re read: too long, written after the decision, or pitched at the wrong audience. Here&amp;#39;s how to write TDDs that actually drive good technical decisions.</description><content:encoded><![CDATA[<p>Technical design documents (TDDs) — sometimes called design docs, RFCs, or tech specs — are one of the most valuable tools available to staff engineers. When done well, they create alignment before implementation, surface risks early, and create a durable record of why decisions were made.</p>
<p>When done poorly, they&rsquo;re ignored, debated endlessly, or written as formalities after the decision is already made.</p>
<p>This post is about writing TDDs that work: getting the right people to the right decision with minimum friction.</p>
<h2 id="when-to-write-a-tdd-and-when-not-to">When to Write a TDD (and When Not To)</h2>
<p>Not every technical change needs a design document. Writing an unnecessary TDD creates process overhead without benefit. A useful heuristic:</p>
<p><strong>Write a TDD when:</strong></p>
<ul>
<li>The change affects more than one team or system</li>
<li>There are multiple viable approaches with real trade-offs</li>
<li>The change is hard or expensive to reverse</li>
<li>The implementation will take more than 1–2 weeks</li>
<li>Stakeholders outside engineering need to understand the approach</li>
</ul>
<p><strong>Don&rsquo;t write a TDD when:</strong></p>
<ul>
<li>The approach is already obvious to everyone involved</li>
<li>It&rsquo;s a well-understood pattern you&rsquo;ve applied before</li>
<li>The cost of getting it wrong is low and easy to fix</li>
<li>You&rsquo;re implementing exactly what was already decided in a previous TDD</li>
</ul>
<p>The signal for skipping a TDD: if you sat down to write one and there&rsquo;s nothing non-obvious to decide, you don&rsquo;t need it.</p>
<p>One exception: when you&rsquo;re new to a team, writing a TDD even for straightforward work builds trust and gives reviewers a window into your thinking. The value there isn&rsquo;t the document — it&rsquo;s the review conversation.</p>
<h2 id="the-sections-that-actually-matter">The Sections That Actually Matter</h2>
<p>Design documents have a lot of conventional sections. Most of them are useful. A few are often missing.</p>
<h3 id="problem-statement">Problem Statement</h3>
<p>This section is frequently too thin. Engineers jump to the solution before establishing the problem clearly enough. A strong problem statement answers:</p>
<ul>
<li>What is broken, missing, or insufficient today?</li>
<li>What is the impact of the current state? (User impact, system impact, operational cost)</li>
<li>What evidence establishes that this problem is real and worth solving?</li>
<li>What is the scope of the problem? (One team? The whole platform? A specific user segment?)</li>
</ul>
<p>If readers don&rsquo;t understand the problem deeply, they can&rsquo;t evaluate proposed solutions. Invest more time here than you think you need.</p>
<h3 id="goals-and-non-goals">Goals and Non-Goals</h3>
<p>Goals should be specific and testable, not vague aspirations. &ldquo;Improve reliability&rdquo; is not a goal. &ldquo;Reduce p99 latency for the checkout API from 2s to 400ms under 1,000 RPS&rdquo; is a goal.</p>
<p>Non-goals are equally important and often omitted. Non-goals:</p>
<ul>
<li>Set scope explicitly (prevents the review from expanding into adjacent problems)</li>
<li>Signal that you&rsquo;ve thought about what you&rsquo;re deliberately not solving</li>
<li>Protect the design from being evaluated against requirements you never intended to meet</li>
</ul>
<p>Write non-goals as explicit statements, not silence. &ldquo;We are not solving X in this proposal&rdquo; is useful. Leaving X unmentioned is not.</p>
<h3 id="background-and-context">Background and Context</h3>
<p>What does a reviewer need to know to evaluate this document who isn&rsquo;t deep in this area? Include:</p>
<ul>
<li>How the relevant systems currently work (high-level)</li>
<li>Prior attempts to solve this problem and why they failed or were abandoned</li>
<li>Constraints that shape the solution space (regulatory, contractual, legacy dependencies)</li>
<li>Why now — what changed that makes this worth solving today</li>
</ul>
<p>This section is easy to underwrite if you assume shared context. Assume less than you think you should.</p>
<h3 id="proposed-solution">Proposed Solution</h3>
<p>The meat of the document. Structure it to answer:</p>
<ul>
<li>What is the approach at a high level?</li>
<li>What are the key components or changes?</li>
<li>How does it satisfy each of the stated goals?</li>
<li>How do the pieces interact? (A sequence diagram or system diagram often conveys this better than prose)</li>
</ul>
<p>Resist the urge to write this section before the others. Engineers who jump to the solution first often write problem statements that are shaped to justify the solution they already want. Write the problem clearly first, then write the solution.</p>
<h3 id="alternatives-considered">Alternatives Considered</h3>
<p>This section is not filler. It&rsquo;s evidence that you explored the space seriously.</p>
<p>For each alternative:</p>
<ul>
<li>What is the approach?</li>
<li>Why might it be preferable?</li>
<li>Why are you recommending against it?</li>
</ul>
<p>The alternatives section also protects you. When a reviewer proposes what you considered and rejected, you can point here instead of relitigating it in the review. It also signals to leadership that you didn&rsquo;t pick the first thing that worked.</p>
<p>Don&rsquo;t list alternatives you didn&rsquo;t seriously consider. One sentence strawmen waste everyone&rsquo;s time.</p>
<h3 id="risks-and-open-questions">Risks and Open Questions</h3>
<p>Name the risks explicitly:</p>
<ul>
<li>What assumptions does this design rely on?</li>
<li>What could go wrong during implementation?</li>
<li>What dependencies could block or invalidate this approach?</li>
<li>What happens to existing users/systems during the transition?</li>
</ul>
<p>Open questions deserve a section because they&rsquo;re honest. Not everything is decided when you write the document. Naming open questions tells reviewers where you need input, and it triggers the right conversations.</p>
<p>Mark open questions with an owner when possible: &ldquo;Decision needed from platform team: [question].&rdquo; Unowned open questions don&rsquo;t get resolved.</p>
<h3 id="implementation-plan-and-rollout">Implementation Plan and Rollout</h3>
<p>Cover:</p>
<ul>
<li>What&rsquo;s the phased rollout plan? (Especially important for changes with production impact)</li>
<li>What&rsquo;s the rollback plan?</li>
<li>What observability will you add to know if it&rsquo;s working?</li>
<li>What&rsquo;s the migration path for existing data or users?</li>
<li>What&rsquo;s the timeline and what are the dependencies?</li>
</ul>
<p>The implementation section separates documents that drive action from documents that sit in a wiki. Reviewers want to know not just what you&rsquo;re building but how you&rsquo;ll build it safely.</p>
<h2 id="writing-for-the-right-audience">Writing for the Right Audience</h2>
<p>Most TDDs have multiple audiences with different needs:</p>
<p><strong>Technical reviewers</strong> (the engineers who will implement this or maintain related systems) need the depth: specific design choices, data models, API contracts, failure modes.</p>
<p><strong>Cross-functional stakeholders</strong> (product, data, security, legal) need the impact and the trade-offs, not the implementation details. If you&rsquo;re sharing a doc with this group, a one-page executive summary at the top saves everyone time.</p>
<p><strong>Future engineers</strong> reading this six months later need context they don&rsquo;t have: why was this chosen over alternatives, what was the state of the system at the time, what constraints applied.</p>
<p>Write with all three in mind. Structure the document so reviewers can navigate to the parts relevant to them. Bury the deeply technical detail in sections that cross-functional stakeholders can skip.</p>
<h2 id="the-review-process">The Review Process</h2>
<p>A TDD with no review process is a document, not a decision mechanism. Structure the review deliberately.</p>
<p><strong>Set a deadline.</strong> &ldquo;Please review by Friday EOD&rdquo; produces responses. &ldquo;Let me know when you&rsquo;ve had a chance to look&rdquo; produces silence.</p>
<p><strong>Designate required reviewers vs. optional.</strong> Required reviewers must sign off. Optional reviewers get to weigh in but can&rsquo;t block. Be explicit about who is in each category.</p>
<p><strong>Time-box the comment period.</strong> Two weeks of open-ended review often results in more confusion than a focused 3-day window. Scope creep in review is a real problem.</p>
<p><strong>Hold a synchronous review meeting for high-stakes designs.</strong> Async comment threads are efficient for small details. For designs that affect multiple teams or have significant architectural implications, a 1-hour synchronous review often resolves more than 2 weeks of async back-and-forth.</p>
<p><strong>Distinguish blocking feedback from non-blocking.</strong> Reviewers should label comments: &ldquo;blocking&rdquo; (must be addressed before approval), &ldquo;suggestion&rdquo; (take or leave), &ldquo;question&rdquo; (just curious). This prevents good-faith questions from becoming approval blockers.</p>
<h2 id="common-failure-modes">Common Failure Modes</h2>
<p><strong>Written after the decision.</strong> The TDD is created to document what&rsquo;s already been decided, not to make the decision. Reviewers are asked to ratify, not evaluate. This produces rubber-stamp reviews and skips the alignment that makes TDDs valuable. The fix: write the TDD before writing code, not after.</p>
<p><strong>Too long to read.</strong> A 30-page design document gets skimmed or skipped. If your TDD is over 10 pages, it&rsquo;s probably covering too much scope or including implementation details that belong in code comments. Aim for 3–6 pages of substantive content.</p>
<p><strong>Pitched at the wrong level.</strong> A highly technical document sent to a VP-level audience, or a high-level document sent to engineers who need to implement it. Write the right document for the right audience, or write a document with a layered structure.</p>
<p><strong>Alternatives section that&rsquo;s a formality.</strong> One-line alternatives that obviously weren&rsquo;t seriously considered signal that you&rsquo;ve already decided and are going through the motions. If you can&rsquo;t write a genuine case for each alternative, remove it — or go back and do the exploration.</p>
<p><strong>Never updated.</strong> The design changes during implementation but the document doesn&rsquo;t. Later engineers read the original document and draw wrong conclusions. Either keep the document updated or add a prominent note: &ldquo;Implementation diverged from this design in the following ways: [link to followup doc].&rdquo;</p>
<h2 id="living-documents-vs-archived-decisions">Living Documents vs. Archived Decisions</h2>
<p>Some TDDs stay relevant long after implementation — architectural decisions, data model choices, API contracts. These should be kept in a stable location and updated when the design evolves.</p>
<p>Others are point-in-time decisions that become irrelevant after implementation. For these, mark them clearly: &ldquo;This design was implemented in Q3 2026. The system now works as described. For current architecture, see [link].&rdquo;</p>
<p>The worst outcome is a design document that describes something that no longer exists, sitting in the same location as current documentation with no indication that it&rsquo;s outdated.</p>
<h2 id="a-minimal-tdd-template">A Minimal TDD Template</h2>
<pre tabindex="0"><code>Title: [What this designs]
Status: Draft / In Review / Approved / Implemented
Author: [Name]
Reviewers: [Required] / [Optional]
Created: [Date]
Last Updated: [Date]

---

## Problem Statement
[What is broken, missing, or insufficient? What&#39;s the impact?]

## Goals
- [Specific, testable goal 1]
- [Specific, testable goal 2]

## Non-Goals
- [Explicitly out of scope: X]
- [Explicitly out of scope: Y]

## Background
[Context reviewers need. Prior attempts. Constraints.]

## Proposed Solution
[High-level approach. Key components. How it satisfies the goals.]

## Alternatives Considered
### Option A: [Name]
[Description, pros, why rejected]

### Option B: [Name]
[Description, pros, why rejected]

## Risks
- [Risk 1: impact, likelihood, mitigation]
- [Risk 2: ...]

## Open Questions
- [Question] — Owner: [Name], Needed by: [Date]

## Implementation Plan
- Phase 1: [...]
- Phase 2: [...]
- Rollback plan: [...]
- Observability: [...]
</code></pre><p>The template is a starting point. Add sections when your design needs them. Remove sections when they&rsquo;d be empty. A TDD that follows a template perfectly but says nothing useful is worse than no TDD at all.</p>
]]></content:encoded></item></channel></rss>