← Back to the section

Picture this: the team spent several days discussing the architecture, walked away happy, and a month later no one remembers what exactly was decided or why. A new colleague proposes the very same options that were already rejected. In production, a failure scenario shows up that nobody considered.

This is exactly why a design has to be written down and put through review. A design that isn't written down is one person's opinion. Review turns it into a shared decision the team can rely on.

What a design doc is

A design doc is a short engineering document that captures: what we're building, why this way, and which options we rejected. Not a presentation for management, not a formal requirements spec — a working document for the team.

A typical structure:

# Notification platform — design doc

Status: in review | Author: ... | Reviewers: ... | Date: ...

1. Context and problem        — why we're building it, what hurts today
2. Requirements               — functional, numbers, anti-requirements
3. Estimates                  — load calculation, conclusions from the numbers
4. Proposed design            — contracts, data model, schema, hot spots
5. Failures and degradation   — a "what's down → what the user sees" table
6. Considered alternatives    — what we rejected and why
7. Forks → ADR                — links to recorded decisions
8. Plan: first version and beyond — what we build now, what's deferred
9. Open questions             — an honest list of the unresolved

Three sections matter the most:

  • Alternatives — without them, reviewers will propose the same options all over again. A year from now a new colleague will bring them back.
  • Failures and degradation — a design without failure scenarios isn't a design.
  • Open questions — if the list is empty, the document is either brilliant or the authors didn't think hard enough. The second is more likely.

The sweet spot is 3–6 pages. No one reads fifteen-page walls of text; details belong in appendices and links. The document lives in git next to the code — then you can review it like a pull request, see its history, and find it easily.

Diagrams: the C4 model

The main mistake when drawing architecture diagrams is one picture for everything: containers, classes, and network zones all in one mess. It's impossible to make sense of.

The C4 model solves this with levels. Each level is its own diagram with a clear audience:

Context — the topmost level. It shows the system and its neighbors: who the user is, which external systems are involved. Understandable to everyone, including non-technical participants.

Container — the main diagram for a design doc. It shows services, databases, queues, and the links between them. What the reader needs to grasp: what the system is made of and how the parts talk to each other.

Component — the internals of a single container. Draw it only for the "hot spots" — the places with real architectural complexity. There's no point doing this for every service.

Code — not drawn by hand. It's either generated from the code or not needed at all.

Practical rules for any level:

  • Label every arrow: what's passed and how (synchronously/asynchronously).
  • Name every element with domain terms — not "Backend" and "Service 2", but "Notification service" and "Delivery queue".
  • Store diagrams as code (mermaid or PlantUML in git) — otherwise they'll be stale by the third review and no one will know whether they're still accurate.

ADR: recording the important forks

During design, forks come up — moments where you can go down two different paths. For example: "Kafka or SQS?", "The feed in PostgreSQL or in MongoDB?".

A design doc describes the final decision as a whole. But each significant fork is worth recording separately — in the ADR (Architecture Decision Record) format.

Why separately? A design doc is read once, at review time. ADRs get found years later when someone asks "why is it done this way here?" — six months on, during a new engineer's onboarding, during an audit. The design doc links to the ADRs; the ADRs outlive the document itself.

More on the format in the ADR article.

How to run a design review

A design review isn't a formality. It's hunting for holes before the code is written. A problem found in review saves weeks of work.

The workflow:

1. Document — ahead of time. At least two days before the meeting, so participants can read it and write comments. A meeting where people see the document for the first time is a reading-aloud session, not a review.

2. Meeting — on the contentious points. Not a retelling of the document, but working through the collected comments and open questions. 60–90 minutes is a reasonable maximum.

3. The right reviewers. 2–4 people is enough. There must be: someone from the operations side of this system and someone from the consumers of its API. A review done only by architects misses exactly the problems that will surface in production and for customers.

4. Outcome — in writing. The decision (approved / approved with changes / rework), the list of required changes, new ADRs. Without a written outcome, a month later no one remembers what was decided.

Useful questions for a reviewer:

  • What are the numbers? Where do they come from? What happens at peak?
  • What does the user see when component X fails?
  • Why is this block here — which requirement called for it?
  • Where's the idempotency on retries?
  • How do we migrate or roll back?
  • What's in the first version, what's deferred?

A question the author has no answer to is a normal result of a review. It goes into the open questions rather than getting closed off with a confident tone.

Common mistakes when defending a design

Design as a presentation. Pretty slides instead of a document: nothing to comment on line by line, nothing to come back to a year later. Slides are shown; documents are examined.

The author gets defensive instead of listening. Questions are taken as an attack rather than help. A review is hunting for holes before production; a hole found is a win for the author, not a defeat.

Review after development has started. When half the code is written, a review can't change anything — it just legalizes what's been done. A design is reviewed before the sprint.

Endless approval. Five rounds of edits from five participants. Solved with a timebox and an explicit decision owner: reviewers advise, one person decides — and writes it down.

"Everyone agrees" by silence. Absence of comments isn't agreement — it's an unread document. Ask for an explicit answer from each reviewer.

In short

  • A design doc is 3–6 pages: context, requirements, estimates, design, failures, alternatives, ADR, plan, open questions.
  • The "Alternatives", "Failures", and "Open questions" sections make the document an honest engineering artifact.
  • The C4 model splits diagrams into levels: Context (for everyone), Container (the main one for a design doc), Component (hot spots only).
  • Diagrams as code in git — otherwise they go stale and no one knows whether they're accurate.
  • An ADR records each important fork separately — they're found for years, while a design doc is read once.
  • The document goes out at least two days ahead; the meeting covers the contentious points, not a retelling.
  • Review is hunting for holes before code is written, not a formality afterward.
  • The review outcome is always recorded in writing.
  • The system design method — the content this document gives shape to.
  • The C4 model — diagram levels in detail.
  • ADR — the format for recording important decisions.
  • What an architect does — whose job it is to drive a design to a decision.