System Design Interview Foundations Course
A structured course covering interview roadmap, capacity estimation, scalability, databases, APIs, microservices, reliability, observability, and security with linked practice questions.
What you will learn
- Explain the system design interview roadmap and clarify requirements.
- Estimate QPS, storage, and capacity with simple calculations.
- Apply load balancing, caching, and CDN to scale services.
- Compare databases, sharding, and consistency using CAP.
- Design APIs, microservices, queues, and reliable observable systems.
Before you start
- Basic programming knowledge
- Familiarity with HTTP, APIs, and databases
- No prior system design interview experience needed
Lesson 1 System Design Interview Roadmap
A system design interview tests how you turn a broad product idea into a clear technical plan. The interviewer wants to see structure, communication, and tradeoff awareness, not a memorized architecture. Start every answer by restating the problem and asking about users, scale, and constraints.
First clarify requirements: who uses the system, how many reads and writes arrive per second, what latency matters, how much data must be stored, and which regions users come from. Write these numbers down because they drive every later decision.
Next make simple capacity estimates. Estimate daily active users, requests per second, storage growth, and bandwidth. Rough calculations such as QPS = DAU x actions per day / seconds are enough to choose between small and large designs.
Then draw a high-level design: clients, load balancers, application services, caches, queues, and databases. Label each component and explain the main request flow before adding detail.
Choose one or two areas to deep dive, such as the data model, API design, sharding strategy, or failure handling. State the tradeoff you are optimizing and compare at least one alternative before committing.
Finish with a short summary: the key components, the main risks, and what you would monitor. A clear ending helps the interviewer follow your reasoning and makes your answer memorable.
Interview loop: restate the problem, clarify requirements, estimate scale, design the high-level architecture, then deep dive into one or two components. Always name tradeoffs and explain how you would measure success.
Example
Interview prompt: "Design a URL shortener." Start with requirements: users, links created per day, reads per link, storage, and expiration. Then state the core flow: client sends a long URL, the service generates a short ID, stores the mapping, and redirects reads with a 301 or 302.
Practice answer: QPS = 1 million links/day / 86,400 seconds ≈ 12 writes/sec, with reads about 100x higher. That small write rate supports a relational database, while reads benefit from caching and CDN-friendly redirects.
Worked example: For a URL shortener, clarify read/write ratio, shortening length, and analytics needs before drawing components.
Lesson 2 Scalability, Load Balancing, and Caching
Scaling is the first thing interviewers test because it connects every component. Vertical scaling adds power to one machine; horizontal scaling adds more machines and is the usual choice for web systems.
A load balancer sits in front of the service, checks health, and routes traffic with strategies such as round-robin or least connections. Layer 7 balancers can also route by URL path and headers.
Caching stores frequently read data close to the caller. Use cache-aside for database reads: check cache, load from the database on a miss, write back, and set a TTL. Choose LRU eviction and decide when to invalidate.
A CDN serves static assets from edge locations and reduces latency for users around the world. It works best for images, JavaScript, CSS, and other immutable content.
For hot keys, one popular item can overwhelm a single cache shard. Spread the key across several shards or add randomness to the cache key, and cache different levels of aggregation separately.
Example: a read-heavy feed can place the API behind a load balancer, cache popular feeds in Redis, and serve static files through a CDN. This keeps database reads low and response time stable.
Scale loop: start with one server, then add a load balancer, horizontal replicas, caching, CDN, and database read replicas as load grows. Cache hot data with TTLs and invalidate carefully to keep consistency.
Example
Design decision: a news feed receives 10,000 reads per second. Place a load balancer in front of API servers, cache the top 1,000 feeds in Redis, and serve avatars and images from a CDN.
Interview follow-up: "What happens when a feed becomes hot?" Spread the cache key across shards and add a short TTL so the database is not overloaded.
Worked example: Profile pages can be cached for 5 minutes; user-specific content stays dynamic.
Lesson 3 Databases, Sharding, and Consistency
Database choice depends on the access pattern. Relational databases work well for structured transactions and joins; NoSQL stores help with flexible schemas, high write volume, or large distributed datasets.
Add indexes for common query paths and denormalize read models when joins become expensive. Read replicas move SELECT traffic off the primary, and failover keeps writes available when a primary fails.
Sharding splits rows by a key using range or hash partitioning. Hash sharding distributes load evenly but makes range queries harder; range sharding helps locality but can create hot shards.
The CAP theorem says a distributed system must choose between consistency and availability during a partition. Strong consistency is simpler to reason about, while eventual consistency scales better and needs reconciliation.
Distributed transactions are expensive. Use idempotent operations, outbox tables, or event-driven workflows instead of trying to make every write atomic across services.
For the interview, name the database, the shard key, the replica strategy, and the consistency model. These four decisions show you understand data at scale.
Data choice drill: choose relational for transactions and joins, NoSQL for flexible or high-volume data, and shard by a stable key. Use indexes, denormalization, read replicas, and failover to handle the access pattern.
Example
Design decision: a chat service stores messages by conversation_id. Hash sharding on that key keeps one conversation in one shard, while a secondary index supports user inbox queries.
Consistency: use strong consistency for message acknowledgment and eventual consistency for read receipts, then reconcile with timestamps.
Worked example: A messaging app stores conversations in a NoSQL store and indexes by user id.
Lesson 4 REST APIs, Microservices, and Message Queues
Clean API design makes a system easier to build and maintain. REST uses resources and HTTP verbs: GET reads, POST creates, PUT replaces, PATCH updates, and DELETE removes. Use status codes such as 201 for created and 429 for rate limited.
Use pagination for large collections. Cursor pagination is more stable when data changes; offset pagination is simpler but can skip or duplicate rows.
Rate limiting protects APIs from abuse. Token bucket and sliding window are common algorithms, and limits are often applied per user or per API key.
Microservices split a product into independently deployable services with clear boundaries. Avoid sharing one database, and use an API gateway to centralize auth, routing, and limits.
Message queues decouple producers and consumers. At-least-once delivery may create duplicates, so consumers should be idempotent; dead-letter queues capture messages that fail repeatedly.
Example: an order service writes an event to a queue, the payment service consumes it, and a separate notification service listens for results. Each service scales and deploys independently.
API drill: design resources with clear verbs and status codes, paginate large collections, and version APIs. Split services by ownership and failure domain, and use queues to decouple slow or bursty work.
Example
API design: GET /users/{id}/orders?cursor=... returns a page of orders with the next cursor. Rate limit by user with a token bucket of 100 requests per minute.
Failure handling: if payment is slow, publish an order event to a queue and let payment consume it; failed payment messages go to a dead-letter queue.
Worked example: Order creation returns 201 and publishes an event; the payment service consumes it asynchronously.
Lesson 5 Reliability, Observability, and Security
A reliable system fails gracefully. Use retries with exponential backoff and jitter for transient errors, and add a circuit breaker to stop calls to a failing service before it exhausts resources.
Bulkheads isolate resource pools so one slow service can not consume all connections. Set timeouts and define fallback behavior for non-critical features.
Observability combines metrics, logs, and traces. Metrics show health, logs explain events, and distributed traces follow one request across services. Define SLIs and SLOs so teams know when action is needed.
Security should be part of the design: TLS for data in transit, authentication at the gateway, least-privilege access, secret management, and rate limiting for public endpoints.
Also discuss cost and capacity: right-size instances, use autoscaling, move cold data to cheaper storage, and avoid idle resources.
Use the linked 50-question bank as a mock review: answer under time pressure, classify mistakes, and redo them after 24 hours, 3 days, and 7 days.
Resilience drill: add retries with backoff and jitter, circuit breakers, timeouts, and bulkheads. Track metrics, logs, and traces, set alerts, and define SLOs. Run failover drills so the system behaves predictably under stress.
Example
Reliability plan: retry a failed payment three times with exponential backoff and jitter, then open a circuit breaker for 30 seconds. Trace the request with a shared request_id and alert when p99 latency exceeds 500 ms.
Security: use TLS, authenticate through the gateway, store secrets in a vault, and rate limit login endpoints.
Worked example: If a dependency fails, serve stale cache instead of returning 500, and record the fallback in logs.