Jump to a problem, path or page
Jump to a problem, path or page
The path
Each module starts from a problem a growing app runs into, explains the idea that solves it, and ends with a design for you to practice.
Part 1
One server to a well-scaled product, in the order a growing app needs it.
The decisions you make when software has to serve real users at real scale, and how to find what a system actually needs.
Part 2
What changes when the data and the work live on many machines.
Split data and traffic across machines, choose keys that avoid hot spots, and move partitions without losing writes or making every query global.
Part 3
The algorithms and data structures big systems are built from.
Trade a little accuracy for huge savings in memory: Bloom filters for membership, HyperLogLog for counting unique items, and count-min sketches for frequencies and top-K.
A repeatable order for designing any system in 45 minutes: requirements, entities, API, high-level design, then deep dives.
The latency and capacity numbers worth memorizing, and how to turn a product sentence into requests per second, storage and bandwidth.
What happens between a click and your server, how to design APIs other people can rely on, and which protocol to pick for which job.
Turn entities into tables or documents, pick the kind of database that fits the access patterns, and use transactions and constraints to keep the data correct.
How databases find rows without reading everything: B-trees, composite and covering indexes, and the specialized indexes behind search and maps.
Why caches work, where they live, how reads and writes flow through them, keeping cached data correct, and what happens when the cache fails.
Bigger machines or more of them, keeping servers stateless, how load balancers choose a server, and planning capacity for peaks.
Read replicas and replication lag, failover and backups, and sharding when one primary can no longer hold the data or the writes.
Move slow and unreliable work off the request path, make consumers safe to retry, and keep backlogs under control.
Protect capacity and share it fairly: where limits belong, the algorithms behind them, and making them work across many servers.
Choose how updates reach clients, push to many open connections, and keep delivery correct through disconnects and retries.
Store large files outside the database, upload and process them safely, and deliver them cheaply through caches near users.
Build an inverted index, rank useful matches, and run a search service whose derived data stays in sync and can be rebuilt.
Core security patterns for system design: authentication mechanisms, fine-grained authorization, encryption with secrets, and API defense against abuse.
Complete, end-to-end demonstrations of the delivery framework applied to classic system design interview problems.
Keep multiple copies, understand what reads can observe, and choose quorum, consistency and conflict rules that match the product's guarantees.
Handle uncertain outcomes, bound retries and cascading failures, and reason about time and stale workers without trusting synchronized clocks.
Use leases and fencing safely, understand what election and consensus provide, and keep coordination small by choosing ownership and operations carefully.
Queues, pub/sub and partitioned logs like Kafka: how they differ, what delivery guarantees really mean, and how to run a log in production.
Keep data consistent when one business action spans several services: the dual-write problem, two-phase commit, sagas and the transactional outbox.
Treat changes as a stream: change data capture and derived data, event sourcing and CQRS, and processing unbounded streams with windows and watermarks.
Measure availability with SLOs and error budgets, remove single points of failure, plan recovery with RPO and RTO, and run across regions.
Monitoring distributed systems with metrics, structured logs, distributed traces, symptom-based alerting, and systematic triage.
Processing petabyte-scale data with distributed batch computation, columnar analytical storage, data lakehouse partitioning, and streaming architectures.
How systems decide which machine owns which key: consistent hashing in depth, virtual nodes and replicas on the ring, and the alternatives (rendezvous, jump hash, bounded loads).
Find what's near a point without scanning everything: geohashes and space-filling curves, quadtrees, and the cell systems (S2, H3) behind maps, ride-hailing and delivery apps.
What happens under a database's API: B-trees that update pages in place, LSM trees that turn writes into appends, and the read, write and space trade-offs that decide which fits.
Hash trees that let systems verify data and find differences cheaply: proofs of inclusion, replica repair, file sync, and content-addressed storage in Git and artifact stores.