Skip to main content

Introduction to System Design

System design is the process of defining the architecture, components and data flow of a system so that it meets its requirements at the required scale.

A repeatable approach​

  1. Clarify requirements: functional (what it does) and non-functional (scale, latency, availability, consistency).
  2. Estimate: users, requests per second, storage, bandwidth.
  3. Define the API and the core data model.
  4. Sketch the high-level design: clients, services, storage, caches, queues.
  5. Deep dive into the bottlenecks and trade-offs.
  6. Review: failures, monitoring, security, cost, evolution.

Non-functional requirements​

TermMeaning
ScalabilityHandle growth in load
AvailabilityFraction of time the system is up
LatencyTime to serve one request
ThroughputRequests handled per second
ConsistencyDo all readers see the latest write?
DurabilityCommitted data is not lost

Availability in "nines"​

AvailabilityDowntime per year
99%about 3.65 days
99.9%about 8.8 hours
99.99%about 53 minutes
99.999%about 5 minutes

Back-of-the-envelope estimation​

Useful numbers:

ItemValue
Seconds per dayabout 86,400 (round to 10^5)
1 million requests per dayabout 12 requests per second
Memory readabout 100 ns
SSD readabout 100 microseconds
Datacenter round tripabout 0.5 ms
Cross-continent round tripabout 150 ms
estimate.py
daily_users = 10_000_000
requests_per_user = 20
qps = daily_users * requests_per_user / 86_400
peak_qps = qps * 3 # typical peak factor
print(round(qps), round(peak_qps)) # ~2315, ~6944

Trade-offs to name explicitly​

  • Consistency vs availability (CAP).
  • Latency vs throughput.
  • Read-optimised vs write-optimised designs.
  • Simplicity vs flexibility; build vs buy.