How to Write a Technical Spec That People Actually Read

Writing Tutorial

How to Write a Technical Spec That People Actually Read

A technical spec is a decision document, not a documentation artifact. This guide covers how to structure one so it surfaces disagreement early, builds shared understanding, and creates a durable record of why the system was built the way it was.

Why most technical specs fail

A technical spec fails when nobody reads it after it is written.

This happens for a predictable reason: most specs are written as documentation of a decision that has already been made, rather than as a tool for making the decision well. By the time the spec is circulated, the author has already decided. The review is performative. Nobody disagrees because the decision is already done.

A spec written as a decision-making tool works differently. It is written before the decision finalizes. It is shared with people who have standing to disagree. It changes based on input. The author does not already know the answer.

That is the posture this guide teaches.

What a technical spec is for

A technical spec has three purposes, in order of priority:

  1. Surface disagreement while it is cheap to change direction — Design-time disagreements are orders of magnitude cheaper than implementation-time disagreements, which are orders of magnitude cheaper than production-time ones.

  2. Build shared understanding across the people affected — Engineering is not the only audience. Product, design, security, and infrastructure teams all have context that belongs in the design. A spec circulated only among engineers misses most of this.

  3. Create a durable record for the people who were not in the room — Three months later, a new engineer joins. A year from now, someone proposes changing the system. The spec is how they understand why it was built this way.

The anatomy of a useful spec

Fig. Technical spec structure
1.
Context and problem statement Why this work exists and what it must solve
2.
Proposed approach The design, with enough detail to evaluate
3.
Alternatives considered What was evaluated and why it was rejected
4.
Open questions and risks What you do not know yet

Context and problem statement

This section exists to answer: why are we doing this work, and what does success look like?

The problem statement should be specific enough that someone who disagrees with the proposed approach could still agree with the problem. If your problem statement is “improve performance,” the spec is not grounded. If it is “reduce P99 latency for the search endpoint from 800ms to under 200ms under production load,” now we can have a technical conversation.

Include: what triggered this work, what the current state is, what the desired state is, and what constraints you are operating under (timeline, budget, backwards compatibility, team size).

Proposed approach

The core of the spec. This section should contain enough detail that a senior engineer who has not seen the problem before could evaluate whether the approach is sound.

What to include:

  • System architecture or data flow (a simple diagram often communicates more than prose)
  • Key technical decisions and the reasoning behind them
  • How the approach handles failure, scale, and edge cases
  • What existing systems or patterns it builds on or breaks from
  • Migration path if replacing an existing system

What to omit:

  • Implementation details that belong in code comments
  • Technology choices that do not affect the design (the spec should not specify which npm package to use)
  • Obvious things — do not explain that HTTP is stateless to engineers who have been using HTTP for years

Alternatives considered

This is the section most specs omit, and it is the most valuable for future readers.

For each alternative you evaluated, write: what it was, why it seemed worth considering, and what disqualified it. The disqualifier is the important part. If the reason was “would take too long to build,” that is decision context. If the reason was “introduces a hard dependency on a vendor we want to reduce exposure to,” that is decision context. If the reason was “the senior architect preferred this approach,” write that too — honestly documenting social constraints is not weakness, it is accuracy.

Open questions and risks

This section is often written at the end as an afterthought, but it is actually a forcing function. Writing it honestly means admitting what you do not know.

List: technical unknowns that could change the design, integration points that depend on teams you have not talked to yet, performance assumptions that have not been validated, security considerations that need a review.

For each open question, note who owns it and when it needs to be resolved. An open question with no owner is not really being tracked.

The review process

A spec circulated via email with “let me know if you have thoughts” will not generate useful feedback. Useful feedback requires a process.

Who should review: the engineers who will build it, the product manager or owner, the infrastructure or platform team if it has system-level impact, security if it involves authentication, authorization, or data handling, and at least one engineer who has no context and can ask the questions an expert would skip.

How to run the review: share the spec at least 48 hours before any meeting. Schedule a synchronous discussion only if there are real disagreements — do not use a meeting to read the spec out loud. If the spec is clear and uncontroversial, async comments are sufficient.

What to do with disagreement: treat disagreement as signal, not friction. A reviewer who pushes back is doing their job. The right response is to engage the substance, not defend the design.

After the spec is approved

Update the spec to reflect the final decision, including any significant changes from the original proposal. Note any dissenting views that were considered and why they were not adopted. Mark the spec as approved with a date.

Then — and this is the part most teams skip — make the spec findable. A spec that lives in someone’s Google Drive folder is inaccessible. A spec linked from the repository, or stored in a /decisions folder alongside the code it describes, will actually be found.

Common spec anti-patterns

The spec that describes the solution without the problem. Starts at the implementation level and never explains why the work exists. Future readers cannot evaluate whether the approach was right for the problem because the problem was never stated.

The spec that is too long to read. A 30-page spec generates 30 pages of skim-reading. Aim for 3-5 pages for a typical feature. System-level redesigns may warrant more, but longer is not better.

The spec written after the build. Documentation of what was built is useful, but it is not a spec. It cannot surface disagreement because there is nothing left to disagree about.

The spec with no alternatives section. Looks comprehensive but is actually incomplete. The decision exists in a context of other options that were available. Without that context, future readers cannot understand whether the decision was right for the constraints that existed at the time.

Filed under engineering leadership , cloud architecture and technical vision .

If this connects with something you are building or untangling, reply by email — the subject line is already written.