System Design Tutorial with Examples.
System design tutorial with runnable examples: APIs, scaling, reliability, data consistency and end-to-end architecture tradeoffs in production systems.
Also known as High-Level Design.
Architecture at a glance
Click any box to open the lesson that teaches it
System design at a glance
client → CDN → rate limit → load balancer → services → cache → database
How it fits together (7 steps)
- A client's request hits the edge first: a CDN cache serves what it can, and a token-bucket rate limiter throttles the rest.
- A load balancer spreads what's left across app instances behind an API gateway, and a circuit breaker stops one call from waiting on a service that's already down.
- Reads go through cache-aside first, with LRU/LFU eviction deciding what survives in a full cache.
- The database layer spreads keys with consistent hashing, splits data with sharding, and survives a primary failure through replication.
- Work that doesn't need to block the response moves to events instead of requests, with queues absorbing bursts through backpressure.
- Shared state needs coordination: a Redis-based lock serialises access to one resource, and leader election picks one coordinator when several nodes could do the job.
- Planning and operating it: capacity estimation turns assumptions into real numbers, retries with backoff trade latency for reliability, ACID vs BASE and consistency under partitions set what a reader can trust, availability arithmetic turns nines into downtime, observability ties logs/metrics/traces into one signal, and a worked URL shortener and quorum consistency walk through two full designs.
Beginner
Start here — no prior experience needed
System Design Essentials: Requirements Into a Real API Contract
Requirements and API design stay abstract until a client actually retries a request. An idempotency key turns that abstraction into working, testable code.
Load Balancing: Round Robin vs Least Connections
Round robin sends every server an equal share regardless of load; least connections adapts to which servers are actually busy right now.
Cache Eviction: When LRU and LFU Actually Disagree
LRU evicts whatever wasn't touched most recently; LFU evicts whatever was touched least often. The same access sequence can make them evict different keys.
Capacity Estimation: Turning Assumptions Into Real Numbers
Back-of-envelope math for QPS, storage, and bandwidth from stated assumptions, computed as real numbers instead of described in prose.
Intermediate
For developers with core concepts down
Scaling & Reliability: Retries With Backoff and Jitter
A naive retry hammers a struggling dependency at a fixed interval. Exponential backoff with jitter spaces retries out and spreads clients apart in time.
Consistent Hashing: Why Adding a Server Shouldn't Remap Everything
Plain modulo hashing remaps most keys when the server count changes. A hash ring with virtual nodes remaps only the fraction that actually has to move.
Rate Limiting: Token Bucket and the Fixed-Window Boundary Bug
A token bucket absorbs bursts then throttles once empty. A naive fixed window lets exactly double its limit through if requests cluster at the boundary.
CDNs and Edge Caching: A Real Cache in Front of a Slow Origin
Put an nginx edge cache in front of a slow origin and watch a MISS become a HIT, s-maxage expire, an ETag revalidate and a stale page survive an outage.
Advanced
Production-grade patterns for experienced engineers
Consensus: A Real Raft-Style Leader Election, Split Vote, and Failover
Simulate a 5-node cluster with real randomized election timeouts — a clean election, a genuine split vote, and a re-election after the leader is killed.
Distributed Locks: A Real Double-Booking Bug, Fixed With a Redis Lock
Two processes racing on the same booking slot really do double-book it. A Redis SET NX PX lock fixes it — a blind DEL unlock reintroduces the bug.
Quorum Consistency: When a Read Is Guaranteed to See the Latest Write
A write acked by W replicas and a read from R only guarantee overlap when W plus R exceeds the replica count -- otherwise a read can miss the latest write.
Also part of System Design
Taught in other topics. Each link opens the lesson in its home topic.
Scaling Patterns: Real Sharding vs a Table That Only Looks Sharded
MongoDB's sharding puts data on genuinely separate machines; MySQL's PARTITION BY divides a table by the same kind of range key but keeps every partition on one server. Both engines' own distribution-reporting tools also turn out to report the wrong numbers.
Killing the Primary and Measuring the Real Failover Time
docker kill the primary node of a real 3-node replica set and time exactly how long the cluster takes to elect a new one from container logs and MongoDB's own timestamps — 9.01 seconds, closely matching the documented default election timeout.
ACID vs BASE: the Lost Update Neither Engine Prevents by Default
A naive read-then-write race loses an update in both PostgreSQL and Redis when neither uses locking — the real difference is that Postgres ships a built-in fix (SELECT ... FOR UPDATE) and a raw key-value GET/SET pair has no equivalent.
Distributed Correctness in Interviews
CAP without the slogan, why exactly-once delivery is impossible but exactly-once processing is not, and idempotency demonstrated rather than asserted.
Events vs Requests: Why the Order Service Doesn't Wait for Email
A synchronous order flow fails outright when email is down; an event-driven one records the order and lets each handler fail independently.
Scaling, Queues, and Backpressure
Why autoscaling reacts too late, Little's law applied to a real queue, and the retry storm that turns a blip into an outage.
Cache-Aside with Redis: Stale Reads, Races and Stampedes
Put Redis in front of a slow database and break it on purpose: a stale read, two invalidation races, a 50-request stampede, and the fix for each, measured.
Circuit Breaker: Stop Calling a Service That's Already Down
Retrying a dead dependency forever wastes time on every caller. A circuit breaker as a real closed-open-half-open state machine, tripped by real failures.
API Gateway: Aggregating Calls With a Fallback
A gateway that calls two backends and combines their responses into one — with a real fallback when one of them is too slow to wait for.
Observability Synthesis: Logs, Metrics, Traces, and Alerts as One Signal
Generate structured logs, aggregate them into metrics, fire an alert off a real threshold breach, and use a trace ID to walk straight back from the alert to the log lines that explain it.
Design a URL Shortener: Sequential Codes vs Real Hash Collisions
Two ways to shorten a URL — a base62 counter that never collides but leaks a pattern, and a hash that needs real collision handling.
Availability, Regions, and the Arithmetic of Nines
What an SLA number actually buys you, RTO versus RPO, why multi-region costs more than twice as much, and the failure modes redundancy does not fix.