System Design¶
System design is about choosing a design that fits stated constraints, not reciting a standard architecture. Start with the users and the problem they need solved, then make assumptions about traffic, data size, latency, availability, and retention explicit.
Case studies and foundations¶
- Capacity estimation for system design interviews — workload modeling, peak traffic, concurrency, storage, bandwidth, replica sizing and failure headroom
- Designing a reliable notification service — multichannel fan-out, user preferences, delivery guarantees, provider behavior, retries and recovery
- Designing a URL shortener — short-code allocation, redirect semantics, edge caching, lifecycle consistency, and abuse controls
- Database sharding for multi-tenant backends — partitioning versus distributed sharding, shard-key choice, tenant locality, virtual buckets, hot tenants, query fan-out, and resharding
What to work through¶
- Requirements clarification and capacity estimation
- API boundaries, data models, and storage choices
- Consistency, partitioning, sharding, replication, and recovery
- Caching, queues, backpressure, and failure isolation
- Observability, service-level objectives, and operational trade-offs
How to structure a design¶
Explain the simplest design that meets the requirements first. Add components only when a constraint justifies them. For each major choice, describe the alternative, the failure mode it addresses, and the new operational cost it introduces.
A strong answer also identifies the likely bottleneck, explains how the system behaves when a dependency is slow or unavailable, and describes how it recovers. No single architecture is correct for every workload.
Learning path¶
Use the editorial roadmap to track upcoming case studies and low-level design exercises. The backend chapters provide supporting material on API semantics, data persistence, caching, rate limiting, and service correctness.