Filter concepts by levelShowing all levels.

System Design · Section 3

Requirements Clarification

Level
beginner
Read
20 min
Concepts
4

What to ask before any component diagram exists: the twelve-item checklist that shapes an architecture, the seven ways traffic can actually arrive, and the two boundaries — consistency and synchronicity — that every field and every workflow step needs drawn explicitly rather than assumed.

System Design overview

What is true here

  1. Twelve questions — users, clients, use cases, read/write pattern, data volume, retention, region, traffic shape, peak traffic, SLAs, security, regulatory constraints — precede any component diagram.
  2. A system is usually several traffic shapes at once — read-heavy, bursty, and interactive can all apply to the same feature.
  3. Consistency is decided per field: strong if a stale read breaks something, eventual otherwise.
  4. Synchronicity is decided per workflow step: synchronous if the caller needs the result, asynchronous otherwise.

What you will be able to do

  • Run through the twelve-question checklist against a real feature request
  • Name every traffic shape that applies to a given system, not just the first one that fits
  • Sort a system's data into strongly consistent vs eventually consistent
  • Sort a workflow's steps into synchronous vs asynchronous

Before the diagram

The checklist and the traffic shape — answered before any component is drawn.

What to identify before drawing boxes

corebeginner

Before drawing a single box in a design, twelve questions should already have answers: who uses it, from what client, doing what, how much data, for how long, from where, how much traffic, and under what SLA, security and legal constraints.

Think of it as

A component diagram drawn before these questions are answered is a guess wearing the costume of a design. Every one of the twelve changes what the "right" architecture actually is.

What we're doing: Work through the twelve-question checklist against one real feature request, showing how much of the design the answers already decide.

clarification.txttext
Feature request: "Build a notifications inbox."

Read/write pattern:  read-heavy (read every app open, written rarely)
Data volume:         ~50 notifications/user x 10M users
Traffic shape:       bursty, 5x average at 9am and 6pm
SLA:                 p95 read under 200ms
Security:            a user can only ever read their own notifications
3
Read-heavy already argues for a cache-aside pattern and read replicas — before any component diagram exists.
4
500M total notifications at steady growth already argues against a design that scans every row on read.
5
A predictable, twice-daily burst argues for autoscaling tuned to that shape, not a flat fleet sized for average load.
7
This single line rules out any design where notifications are looked up by anything other than user id — a full-table scan cannot hold 200ms at this volume.

Why this works: Each answer above already narrows the design space before a single box is drawn. Skipping the clarification step does not remove these constraints — it just means the first architecture sketched has to guess at them, and often guesses wrong.

Jumping straight to "we'll use Postgres and Redis"

Wrong

text
Interviewer: "Design a notifications inbox."
Candidate: "I'll use Postgres for storage and Redis
for caching." (draws a diagram)

Better

text
Interviewer: "Design a notifications inbox."
Candidate: "Before I pick storage — is this read-heavy
or write-heavy? What's the data volume and retention
period? Is this single-region? What SLA is it held to?"
(clarifies, then draws a diagram informed by the answers)

What you see: The chosen storage and caching layer turn out to be wrong for the actual read/write ratio or data volume, and the rest of the design session is spent justifying a choice that was never grounded in the requirements.

Why: Naming a specific technology before the twelve questions are answered is designing from familiarity, not from requirements — the same failure mode L103 in this roadmap calls "starting with technologies instead of requirements."

Twelve questions, four themes

Who and how

Users

who is served

Clients

web, mobile, API

Use cases

real workflows

Shape and scale

Read/write pattern

which dominates

Data volume

how much, how fast

Retention

how long kept

Traffic

Regional scope

one region or many

Traffic shape

steady or bursty

Peak traffic

the number to survive

Bounds

SLAs

availability, latency targets

Security

auth, encryption, access

Regulatory

residency, compliance

  • Who and how
    • Users — who is served
    • Clients — web, mobile, API
    • Use cases — real workflows
  • Shape and scale
    • Read/write pattern — which dominates
    • Data volume — how much, how fast
    • Retention — how long kept
  • Traffic
    • Regional scope — one region or many
    • Traffic shape — steady or bursty
    • Peak traffic — the number to survive
  • Bounds
    • SLAs — availability, latency targets
    • Security — auth, encryption, access
    • Regulatory — residency, compliance

The twelve questions, and what each one decides

The twelve questions, and what each one decides
QuestionDecides
Userswho the system ultimately serves
Clientsweb, mobile, API, another service — shapes the API surface
Use casesthe actual workflows, not just "CRUD"
Read/write patternread-heavy vs write-heavy — flips the storage choice
Data volumehow much is stored, and how fast it grows
Retention periodhow long data must be kept, and when it can be deleted
Regional scopeone region or many — flips replication strategy
Traffic shapesteady, bursty, seasonal — changes capacity planning
Peak trafficthe number the system must survive, not the average
SLAsthe availability and latency numbers the design is held to
Security requirementsauth, encryption, access boundaries needed
Regulatory constraintsdata residency, industry compliance rules

Together

text
Feature request: "Build a notifications inbox."

  Users:              logged-in app users
  Clients:             iOS, Android, web
  Use cases:           view unread, mark read, delete
  Read/write pattern:  read-heavy — read on every app open, written rarely
  Data volume:         ~50 notifications/user, 10M users
  Retention:           90 days, then archived
  Regional scope:      single region for now
  Traffic shape:       bursty at 9am and 6pm
  Peak traffic:        5x average during those windows
  SLA:                 p95 read under 200ms
  Security:            a user can only read their own notifications
  Regulatory:           none beyond standard data protection

Remember: Twelve questions before any box is drawn: users, clients, use cases, read/write, volume, retention, region, traffic shape, peak, SLA, security, regulatory.

See also: traffic shape · what is system design

Naming the traffic shape

corebeginner

Seven words describe how load actually arrives at a system: read-heavy, write-heavy, bursty, interactive, batch-oriented, real-time, or event-driven — and each one points toward a different architecture.

Think of it as

A system is rarely just "high traffic." It has a shape — mostly reads or mostly writes, smooth or spiky, waited-on-by-a-human or processed-in-the-background — and that shape decides more of the architecture than the raw request count does.

text
A system can be more than one shape at once:
  a social feed  = read-heavy + bursty + interactive
  a log pipeline = write-heavy + batch-oriented
  a chat app     = interactive + real-time + event-driven

What we're doing: Name every applicable traffic shape for one real system, and show how each shape argues for a specific design choice.

traffic-shape.txttext
System: a social media feed.

  Read-heavy:   a post is read thousands of times, written once
  Bursty:       a viral post spikes read traffic 100x in minutes
  Interactive:  a human is waiting for the feed to render
  Event-driven: a new post triggers fan-out to followers' feeds
3
Read-heavy argues for caching the rendered feed rather than recomputing it on every read.
4
Bursty argues for autoscaling and a caching layer that can absorb a spike without hitting the database directly.
5
Interactive sets a hard latency budget — a feed that takes 3 seconds to load has failed regardless of how correct the data is.
6
Event-driven argues for a queue between "post created" and "fan out to followers" rather than doing the fan-out synchronously in the write request.

Why this works: A system is usually more than one shape at once, and each shape it carries argues for a specific, different design decision. Naming all of them up front is what keeps the eventual architecture from optimizing for the wrong one.

Describing traffic only by volume, never by shape

Wrong

text
"We get 10,000 requests per minute." (no mention of
whether it is read or write, steady or bursty)

Better

text
"We get 10,000 requests per minute — 95% reads,
and it is bursty: a normal minute sees 2,000, but a
push notification can spike it to 10,000 within seconds."

What you see: A system is provisioned for a flat 10,000 req/min average and falls over during the actual spike, because "10,000 requests per minute" hid that the real number was a burst on top of a much smaller baseline.

Why: A raw volume number says nothing about read/write ratio or smoothness. Two systems with the same total request count can need completely different architectures if one is steady and read-heavy while the other is bursty and write-heavy.

A social feed, named across every applicable shape

Read-heavy

read thousands of times, written once

Bursty

a viral post spikes reads 100x

Interactive

a human is waiting on it

Event-driven

a new post triggers fan-out

  • Read-heavy — read thousands of times, written once
  • Bursty — a viral post spikes reads 100x
  • Interactive — a human is waiting on it
  • Event-driven — a new post triggers fan-out

The seven traffic shapes

The seven traffic shapes
ShapeMeansPoints toward
Read-heavyreads far outnumber writescaching, read replicas
Write-heavywrites far outnumber readswrite throughput, partitioning
Burstyload spikes sharply at timesautoscaling tuned to the spike
Interactivea human is waiting on the responselow latency over high throughput
Batch-orientedwork runs on a schedule, no one waitsthroughput over latency
Real-timeresults are needed within a tight windowstreaming, not polling
Event-drivenwork is triggered by events, not requestsqueues, brokers, async processing

Together

text
System: a social feed.

  Read-heavy:     yes — a post is read thousands of times, written once
  Bursty:         yes — a viral post spikes read traffic sharply
  Interactive:    yes — a human is waiting for the feed to load
  Event-driven:   partially — a new post triggers fan-out to followers

Remember: Seven shapes, usually several at once: read-heavy, write-heavy, bursty, interactive, batch-oriented, real-time, event-driven — each argues for a design choice.

See also: clarifying checklist · consistency boundary

Advertisement

The two boundaries

What can be loose and what must be exact — for data, and for workflow steps.

Drawing the consistency boundary

standardbeginner

Every piece of data needs one of two labels: strongly consistent (every read sees the latest write immediately) or eventually consistent (a read may briefly see stale data). Deciding this per field is the actual clarification step.

Think of it as

Ask, for each piece of data: "if a read is a few seconds stale here, does anything break?" If yes — a double charge, a security check, an inventory going negative — it is strongly consistent. If a stale view is merely a little embarrassing, it can be eventual.

text
Strongly consistent:   account balance, inventory count,
                        anything that gates a decision
Eventually consistent: like counts, view counts,
                        "last seen" timestamps, search index
One question, asked per field: if this read is a few seconds stale, what breaks?

Strong — something breaks

  • +Account balance — a stale read lets someone overdraw
  • +Inventory count — a stale read oversells the stock
  • +Permission or role check — a stale read grants access that was just revoked
  • +Price on a product page — a stale read charges the wrong amount
  • +The pattern: it gates a decision

Eventual — barely noticeable

  • Like count — off by a few for a moment harms nobody
  • Search index — a just-created post missing briefly is acceptable
  • "Last seen" timestamp — nothing depends on it being exact
  • "Recently viewed" list — a stale list is harmless
  • The pattern: it is displayed, not decided on
  • Strong — something breaks
    • Account balance — a stale read lets someone overdraw
    • Inventory count — a stale read oversells the stock
    • Permission or role check — a stale read grants access that was just revoked
    • Price on a product page — a stale read charges the wrong amount
    • The pattern: it gates a decision
  • Eventual — barely noticeable
    • Like count — off by a few for a moment harms nobody
    • Search index — a just-created post missing briefly is acceptable
    • "Last seen" timestamp — nothing depends on it being exact
    • "Recently viewed" list — a stale list is harmless
    • The pattern: it is displayed, not decided on

Sorting real data by the consistency it actually needs

Sorting real data by the consistency it actually needs
DataNeedsBecause
Account balancestronga stale read could allow overdrawing
Inventory countstronga stale read could oversell stock
Like count on a posteventualoff by a few for a moment is harmless
Search indexeventuala just-created post missing briefly is acceptable
"Last seen" timestampeventualnothing depends on it being exact
Permission/role checkstronga stale read could grant access that was just revoked

Together

text
Feature: an e-commerce product page.

  Price:             strong   — must reflect the current price
  Stock count:       strong   — prevents overselling
  Review count:       eventual — off by a few is fine
  "Recently viewed":  eventual — a stale list is harmless

Remember: Decide consistency per field, not per system — "a stale read here breaks something" means strong; "a stale read here is barely noticeable" means eventual.

See also: traffic shape · sync vs async boundary

Drawing the synchronous boundary

standardbeginner

Every workflow step needs a decision: must it finish before the response goes back (synchronous), or can it happen afterward, off the request path (asynchronous)? Confusing the two is why "fast" APIs quietly do too much work inline.

Think of it as

Ask, for each step: "does the caller need this result to know their request succeeded?" If yes, it is synchronous. If the caller only needs to know the request was accepted, and the actual work can finish later, it is asynchronous.

text
Synchronous:   validate input, charge a payment,
               anything the caller needs the RESULT of
Asynchronous:  send a confirmation email, update a
               search index, generate a thumbnail
Place an order — everything above the response, and everything after it
caller needsthis resultcaller needsthis resultqueuedqueuedqueued

POST /orders

Validate the order

The caller needs to know if it failed

Charge the payment

The caller needs the charge result

Update the inventory count

Must reflect this order immediately

201 Created

The boundary. Everything below is off the request path

Send the confirmation email

Generate the invoice PDF

Award loyalty points

  • POST /orders
    • leads to Validate the order
  • Validate the order — The caller needs to know if it failed
    • leads to Charge the payment (caller needs this result)
  • Charge the payment — The caller needs the charge result
    • leads to Update the inventory count (caller needs this result)
  • Update the inventory count — Must reflect this order immediately
    • leads to 201 Created
  • 201 Created — The boundary. Everything below is off the request path
    • leads to Send the confirmation email (queued)
    • leads to Generate the invoice PDF (queued)
    • leads to Award loyalty points (queued)
  • Send the confirmation email
  • Generate the invoice PDF
  • Award loyalty points

Sorting a real workflow into synchronous vs asynchronous steps

Sorting a real workflow into synchronous vs asynchronous steps
StepBoundaryBecause
Validate the ordersynchronousthe caller needs to know if it failed
Charge the paymentsynchronousthe caller needs the charge result
Send a confirmation emailasynchronousthe order succeeds whether or not the email sends immediately
Generate an invoice PDFasynchronouscan finish seconds after the response
Update the recommendation modelasynchronousnothing about this request depends on it

Together

text
Workflow: place an order.

  Validate + charge payment:   synchronous — response depends on it
  Send confirmation email:     asynchronous — queued after response
  Update inventory count:      synchronous — must reflect immediately
  Generate loyalty points:     asynchronous — can lag by seconds

Remember: A step is synchronous only if the caller needs its result to know the request succeeded — everything else belongs off the request path, queued for later.

See also: consistency boundary · clarifying checklist

Advertisement