Skip to main content

System Design Process

A structured process for moving from a problem statement to a defensible system design. Applies equally to software design interviews, architecture reviews, and agent-assisted design tasks. The process is iterative — revisit earlier steps as constraints sharpen.

Step 1: Requirements Clarification

Before drawing any boxes, define what the system must do and what constraints it operates under. Ambiguous requirements produce the wrong architecture.

Functional requirements (what the system does)

  • Who uses this system and how? (end users, internal services, third-party integrations)
  • What are the core use cases? List the 3–5 most critical user flows.
  • What are the inputs and outputs?
  • What operations must be supported? (read, write, delete, search, stream, etc.)

Non-functional requirements (how well the system does it)

Common mistakes at this step

  • Jumping to solutions before requirements are clear
  • Treating all requirements as equally important — force-rank them
  • Ignoring failure cases: what happens when a dependency is down?
  • Not asking about the read/write ratio — it drives almost every subsequent decision

Step 2: Capacity Estimation

Back-of-the-envelope calculations to bound the design space. Do not skip this — it determines whether you need sharding, caching, a CDN, or none of the above.

QPS estimation

Storage estimation

Example: 10M messages/day × 1 KB/message × 5 years ≈ 18 TB

Bandwidth estimation

Latency reference numbers (memorize these)

These numbers constrain which designs are viable. If your design requires 5 database reads per request and each read is 1 ms, you cannot achieve a 2 ms p99.

Step 3: High-Level Component Decomposition

Sketch the major components and their interactions before designing any one of them in detail.

Standard component checklist

  • Client layer: web, mobile, third-party API consumers
  • Load balancer / reverse proxy: traffic distribution, SSL termination
  • Application servers: stateless services handling business logic
  • Caching layer: Redis/Memcached for hot reads
  • Primary datastore(s): SQL or NoSQL per access pattern
  • Message queue: async work, decoupling producers from consumers
  • CDN: static assets, geographically distributed content
  • Background workers: jobs, batch processing, retries

Decomposition heuristics

  • One box per bounded responsibility — if a box does two things, split it
  • Draw the data flow, not just the components: where does data enter, transform, and exit?
  • Identify the single point of failure in your first sketch — every design has one; acknowledge it
  • Ask: which component fails most often? Design for that failure first.

Step 4: Data Flow Mapping

Trace the path of a request from client to storage and back. For each hop, identify:
  • What protocol is used? (HTTP/REST, gRPC, message queue, WebSocket)
  • Is this synchronous or asynchronous?
  • What are the consistency requirements at this boundary?
  • What happens if this hop fails?

API contract design first

Define the API before implementing the internals. This forces clarity on:
  • What data does the client actually need?
  • What operations are exposed?
  • What are the latency SLAs for each endpoint?
API-first prevents over-building: internal services often end up exposing data that no client uses, creating maintenance burden. Example structure for a REST endpoint spec:

Step 5: Tradeoff Articulation

Every design decision involves competing constraints. A good design articulates these explicitly rather than pretending they don’t exist.

Common tradeoff axes

How to reason about competing constraints

  1. State the constraint: “we need < 100ms p99 latency”
  2. Identify what violates it: “5 synchronous DB reads per request at 20ms each = 100ms before any compute”
  3. Name the tradeoff: “we can cache the top 80% of hot reads in Redis at the cost of up to 1s staleness”
  4. Assert acceptability: “1s staleness is acceptable because [business reason]”
Tradeoffs that are not articulated are not made consciously — they are hidden risks.

Step 6: Scale the Design

Only after a working baseline exists, identify bottlenecks and address them with targeted techniques. Scaling interventions in rough order of complexity:
  1. Add caching (cheapest; reduces DB load significantly)
  2. Add read replicas (read-heavy workloads)
  3. Vertical scale (buy time; not a long-term solution)
  4. Horizontal scale / stateless services (application layer)
  5. Database sharding (when a single DB node is the bottleneck)
  6. CDN (static assets, geographically distributed reads)
  7. Async offload via message queue (decouple slow operations)
See Scalability and Reliability for implementation detail on each.

Common Interview / Design Mistakes


Cross-references