Skip to content
SparkTime, home
System Design From Zero to Interview-Ready
Lessons
1 · System Design Foundations
2 · APIs and Communication
3 · Capacity Estimation
4 · Core Building Blocks
5 · Databases
6 · Distributed Systems
7 · Reliability and Operations
8 · Architecture and Security
9 · Interview Method and Foundation Case Studies
10 · Real-World Case Studies
11 · Large-Scale Case Studies
12 · Interview Readiness
Lesson 1 of 45

Lesson 1 · System Design Foundations

Start Here: What System Design Is and How to Learn It

What system design actually is, why interviews test it, the components you will meet and the problem each one solves, and the seven-phase method this 45-article course uses for every design, from a first single-server app to large distributed systems.

On this page

Key takeaways

  • System design is deciding which components a system needs, how they connect, and how data flows, so that the system meets its requirements at the expected scale.
  • Every component exists to solve a specific problem. Ask "why is this here?" before adding anything.
  • Start simple, find what breaks first, and scale only that. Then ask what happens when each part fails.
  • This course uses one seven-phase method everywhere: Clarify, Estimate, Interface, Data, Baseline, Scale, Harden.
  • SDE-1 interviews reward clear fundamentals and sensible trade-offs; SDE-2 interviews add depth on consistency, failure and data at scale.

Most people meet system design through a diagram. Someone shows a picture with a load balancer, three servers, a cache, a database, a queue and a CDN, and says "this is how a real system looks". The learner memorises the picture. Then an interviewer asks them to design a parking-ticket system or a notification service, and the memorised picture does not fit. They add a cache because diagrams have caches, and a queue because diagrams have queues, and cannot explain why either is there.

This course takes the opposite route. You will learn why each part exists, starting from one server, and add parts only when a real problem demands them. By the end you will be able to design systems you have never seen before, estimate how big they need to be, and explain what happens when pieces fail. That is what interviews and real jobs actually ask.

What you will learn

#
  • What "system design" means, and how high-level design differs from low-level design.
  • Why companies ask system-design questions, and what they are really checking.
  • How a simple app grows from one server into a distributed system, one problem at a time.
  • The common components (DNS, CDN, load balancer, application servers, cache, database, queue, workers, object storage, search) and the problem each solves.
  • The seven-phase method used in every article and case study of this course.
  • What changes between SDE-1 and SDE-2 expectations.
  • How to study this course so it sticks.

What system design means

#

System design is the work of deciding which components a software system needs, how they connect, how data moves between them, and how the whole thing behaves under load and under failure, so that it meets its requirements.

Requirements are the anchor. "Design a photo-sharing app" is not a design problem yet. "Let 2 million people a day upload photos and see their friends' photos within a second, without losing any photo" is. The second sentence gives you something to design for.

There are two common levels of design:

Level

Question it answers

Typical output

In this course?

High-level design (HLD)

Which services, databases, caches and queues do we need, and how does a request flow through them?

Boxes and arrows, APIs, data model, capacity numbers, trade-offs

Yes, this is the whole course

Low-level design (LLD)

How is one component structured inside? Which classes, interfaces and design patterns?

Class diagrams, method signatures, patterns such as Strategy or Observer

No. It is mentioned where useful and covered by a separate collection

When an interviewer says "system design round" without qualification, they almost always mean HLD.

The architecture is not the programming language

#

An API server can be written in Java, Go, Python, Node.js, C# or Rust. A load balancer does not care. A cache does not care. The design decisions in this course (where to cache, how to split data, what to do when a call times out) are the same whatever language the services are written in.

This course uses Java for a few small runnable programs, because the wider learning path on this site uses Java. Those programs model an idea, such as how a token bucket refills or how consistent hashing moves keys. They are never the point. If you work in another language, read the Java as pseudocode.

Why companies ask system-design questions

#

Here is the honest version, without hype.

  • It shows how you think about trade-offs. Most real engineering decisions have no single right answer. Caching makes reads faster but data can go stale. Splitting a database across machines adds capacity but makes some queries harder. Interviewers want to hear you weigh both sides.
  • It shows whether you ask before you build. Strong candidates clarify requirements before drawing anything. Weak ones draw a diagram from memory.
  • It shows whether you think about failure. Real systems lose machines, networks drop packets and dependencies slow down. A design that only works on the happy path is not a design.
  • It shows how you communicate. You must explain a structure out loud, keep the interviewer with you, and change course when they push back.

What it is not: a test of how many technology names you know. Saying "Kafka, Redis, Kubernetes, microservices" in the first two minutes is a common way to lose points, because it signals pattern-matching instead of reasoning.

From one server to many: how systems grow

#

The best way to understand the components is to watch a system need them. Let us follow a hypothetical photo-sharing app called Pixly as it grows. The numbers are illustrative.

Stage 1: one machine does everything

#

On day one, Pixly runs on a single server. The web application, the database and the uploaded photos all live on the same machine.

Code
  Browser / mobile app          |          v  +----------------------------+  | One server                 |  |  - application code        |  |  - database                |  |  - photo files on disk     |  +----------------------------+

This is a perfectly good design for a few hundred users. It is cheap and simple, and there is only one thing to fix when something breaks. Starting here is not naive. Staying here after it stops working is.

Stage 2: the database gets its own machine

#

Pixly grows. The database and the application compete for the same CPU and memory, and a heavy query slows down every page. We move the database to its own server. Now each can be sized for its own work.

Code
  Clients     |     v  App server  ---->  Database server

Problem solved: resource contention between two kinds of work.

Stage 3: more application servers, and a load balancer

#

At peak hours, one application server cannot handle all the requests. We could buy a bigger machine (vertical scaling), but there is a limit and a bigger machine is still one machine that can fail. Instead we run several identical application servers (horizontal scaling) and put a load balancer in front to spread requests between them.

Code
  Clients     |     v  Load balancer     |------------|------------|     v            v            v  App 1        App 2        App 3     \            |            /      \-----------+-----------/                  v              Database

Problem solved: more request capacity, and no single application server whose failure takes the site down. This only works if any server can handle any request, which is why the servers are kept stateless. Article 08 explains this.

Stage 4: a cache for repeated reads

#

Most requests read the same popular data again and again: profile pages, photo captions, like counts. The database does the same work repeatedly. We add a cache, an in-memory store that keeps copies of frequently read data so most reads never reach the database.

Problem solved: database read load and read latency. New problem created: the cache can hold stale data. Article 09 is about managing that.

Stage 5: photos move to object storage and a CDN

#

Photo files fill the disks of the application servers, and every server needs access to every photo. We move photos to object storage, a service built to store huge numbers of files durably, and serve them through a CDN (content delivery network), a set of servers around the world that keep copies close to users.

Problem solved: file storage that does not depend on any one server, and fast downloads for users far from our data centre.

Stage 6: slow work moves to a queue

#

When a user uploads a photo, Pixly also creates thumbnails, scans the image and notifies followers. Doing all that before replying makes uploads slow, and if the notification step fails the whole upload fails. We put a message queue between the upload and the follow-up work. The upload request saves the photo, puts a message on the queue and returns. Workers take messages from the queue and do the slow work in the background.

Problem solved: fast responses, and failures in follow-up work no longer break the main request.

The pattern behind the stages

#

Look at what happened. We never added a component because "real systems have one". Each time, a specific problem appeared (contention, request volume, repeated reads, large files, slow follow-up work), and we added the smallest thing that solved it. Each addition also brought a new cost or risk that we now have to manage.

That is the whole discipline in miniature:

  1. Start with the simplest design that meets the requirements.
  2. Ask "What breaks first?" as load grows.
  3. Fix that bottleneck, and only that one.
  4. Ask "What happens when this new part fails?"
  5. Repeat.

The common components, and why each exists

#

Here is the mental model you will use throughout the course. It shows the components a request may pass through, in the order it usually meets them.

Code
  CLIENT (browser, mobile app, another service)     |     v  DNS                    turns a name into an address     |     v  CDN / EDGE             serves cached static content near the user     |     v  LOAD BALANCER          spreads requests across healthy servers     |     v  API / APPLICATION      runs the business logic  SERVERS     |            \     v             \--> CACHE            fast copies of hot data  DATABASE              (checked before the database)     |     v  MESSAGE QUEUE /        hands work to be done later  STREAM     |     v  ASYNC WORKERS          do slow or background work     |     v  OBJECT STORAGE /       files; full-text search; other services  SEARCH / OTHER

Component, problem, common implementations

#

Cloud providers sell managed versions of most components. They are useful as concrete examples, but they are not the thing to learn. Learn the problem and the concept; the product names follow. The names below are examples as of October 2026, and providers rename and merge products regularly.

Component

Problem it solves

Example implementations

DNS

People use names; networks route to addresses

Amazon Route 53, Google Cloud DNS, Azure DNS; self-hosted servers such as BIND or CoreDNS

CDN

Users far from your servers wait a long time for static files

Amazon CloudFront, Google Cloud CDN, Azure Front Door, Cloudflare

Load balancer

One server cannot handle all requests or survive failure

AWS Elastic Load Balancing (Application and Network Load Balancers), Google Cloud Load Balancing, Azure Load Balancer and Application Gateway; NGINX, HAProxy, Envoy

Compute

Somewhere to run your code

Virtual machines (Amazon EC2, Compute Engine, Azure VMs), containers on Kubernetes (EKS, GKE, AKS) or simpler container services, serverless functions

Cache

The database repeats the same expensive reads

Redis or Valkey, Memcached; managed as Amazon ElastiCache, Google Memorystore, Azure Managed Redis

Relational database

Structured data with relationships and transactions

PostgreSQL, MySQL; managed as Amazon RDS or Aurora, Cloud SQL, Azure Database for PostgreSQL

Non-relational database

Very large scale or flexible data with simple access patterns

Amazon DynamoDB, Google Bigtable and Firestore, Azure Cosmos DB; Cassandra, MongoDB

Object storage

Huge numbers of files (images, video, backups) stored durably

Amazon S3, Google Cloud Storage, Azure Blob Storage; Ceph

Message queue

Work should happen later, reliably, at a controlled pace

Amazon SQS, Azure Service Bus, Google Cloud Tasks; RabbitMQ

Pub/sub and event streams

Many consumers need the same events, sometimes with replay

Apache Kafka (or Amazon MSK), Amazon SNS and Kinesis, Google Pub/Sub, Azure Event Hubs

Search engine

Full-text search and ranking that databases do poorly

Elasticsearch, OpenSearch (and Amazon OpenSearch Service), Apache Lucene-based engines

Observability

You cannot fix what you cannot see

OpenTelemetry, Prometheus, Grafana; Amazon CloudWatch, Google Cloud Observability, Azure Monitor

If you can say "we need a durable queue so uploads return quickly and failed thumbnail jobs are retried; on AWS that might be SQS, or we could run RabbitMQ", you have shown the concept first and the product second. That is the order interviewers want.

Three questions to ask about every design

#

Keep these three questions in your head for the whole course. They are more useful than any diagram.

  1. Why is this component here? Name the problem it solves. If you cannot, remove it.
  2. What breaks first? As traffic or data grows, which part reaches its limit first: CPU on the app servers, database writes, database reads, network bandwidth, disk space?
  3. What happens when this fails? If this server, cache, queue or network link disappears for five minutes, what do users see, and what data could be lost or duplicated?

You will see these questions in every article. By the end they should feel automatic.

The seven-phase design method

#

Every design in this course, from a URL shortener to a ride-hailing platform, follows the same seven phases. Article 29 expands them into a 21-item interview checklist, but the phases are enough to start.

Phase

What you do

Key output

1. Clarify

Ask questions. Agree the functional requirements (what it does) and non-functional requirements (how well: latency, availability, consistency, durability, security)

A short, agreed list of requirements, and what is out of scope

2. Estimate

Turn users into requests per second, storage, bandwidth and cache size, with stated assumptions

Rough numbers that tell you which parts are hard

3. Interface

Define the main APIs: endpoints, requests, responses, status codes, idempotency where needed

A handful of API definitions

4. Data

Identify entities, keys, relationships and access patterns; choose storage

A data model shaped around how data is read and written

5. Baseline

Draw the simplest architecture that meets the requirements; walk one request through it

A diagram and a request flow

6. Scale

Ask what breaks first, fix that bottleneck, repeat

An evolved diagram with a reason for every addition

7. Harden

Discuss failures, reliability, consistency, security, observability and trade-offs, then summarise

A defended design and a two-minute summary

Notice that architecture appears only in phase 5. Phases 1 to 4 decide what the architecture must do. Skipping them is the most common beginner mistake.

SDE-1 and SDE-2: what changes

#

Interview expectations vary by company, so treat this as a general guide rather than a rulebook.

Area

SDE-1 (entry level)

SDE-2 (mid level)

Requirements

Asks sensible clarifying questions; separates functional from non-functional

Drives the scope, makes trade-offs between requirements explicit

Estimation

Converts users to QPS and storage correctly with round numbers

Uses the numbers to justify decisions (for example "writes are 2,000 per second, so one primary is fine")

Architecture

Produces a clean baseline with load balancer, stateless servers, database, cache and queue where justified

Evolves the design under load, chooses partitioning and replication strategies

Data

Sensible schema, keys and indexes

Partition keys, hot partitions, replication lag, consistency per operation

Failure

Mentions retries, timeouts and redundancy

Reasons about duplicates, idempotency, partial failure, failover and data loss windows

Depth

Explains each component's purpose clearly

Goes deep on two or three areas when asked, and defends choices under pressure

This course is built to serve both. Articles 01 to 13 and the first three case studies are the SDE-1 core. Articles 14 to 28 and the later case studies add SDE-2 depth. Each article tells you its level.

How the course is organised

#

Module

Articles

What it builds

1. System Design Foundations

01 to 03

This roadmap, requirements, and how a request travels

2. APIs and Communication

04 to 05

API design; synchronous, asynchronous and real-time communication

3. Capacity Estimation

06 to 07

From users to QPS, storage, bandwidth, cache and servers

4. Core Building Blocks

08 to 11

Load balancers, caches, CDNs and object storage, queues and streams

5. Databases

12 to 17

Modelling, indexes, transactions, replication, sharding, choosing a database

6. Distributed Systems

18 to 22

Partial failure, consistency, idempotency, distributed transactions, coordination

7. Reliability and Operations

23 to 25

Fault tolerance, disaster recovery, observability

8. Architecture and Security

26 to 28

Monolith to microservices, event-driven design, security

9. Interview Method and Foundation Case Studies

29 to 32

The interview framework, URL shortener, rate limiter, distributed cache

10. Real-World Case Studies

33 to 39

Notifications, chat, feed, autocomplete, scheduler, ticket booking, payments

11. Large-Scale Case Studies

40 to 44

Video streaming, ride-hailing, food delivery, e-commerce, web search

12. Interview Readiness

45

Practice plan, rubric, extra problems, job-ready checklist

Read in order. Each article builds on the ones before it. Capacity estimation comes before the building blocks on purpose: you need numbers to know whether a component is necessary.

How to study each article

#

Reading about architecture is not the same as being able to produce one. Use this routine:

  1. Read once for the idea. Aim to explain it to a friend in two sentences.
  2. Redraw the diagrams from memory. On paper, without looking. Then compare.
  3. Redo the numbers yourself. Estimation is a skill of the hands, like arithmetic.
  4. Say it out loud. Explain the design as if to an interviewer. You will find the gaps quickly.
  5. Do the exercises before opening the solutions. Struggle for 15 to 20 minutes first.
  6. Revise. Come back after a day, a week and a month. Article 45 has a schedule.

Common mistakes when starting system design

#
  • Starting with technology names. "We'll use Kafka" before anyone knows whether there is anything asynchronous to do.
  • Skipping requirements. Designing for "scale" without knowing whether that means a thousand users or a hundred million.
  • Drawing the final architecture first. Interviewers want to see how you get there.
  • Ignoring numbers. Without estimates you cannot tell whether one database is enough.
  • Only the happy path. Not asking what happens when the cache, the database or a network link fails.
  • Treating one design as "correct". Most questions have several good answers with different trade-offs. Say which one you chose and why.
  • Memorising company architectures. Published descriptions of famous systems are interesting, but they solve those companies' problems, at their scale, with their history.

Progress checklist

#

Copy this into your notes. "Done" means you read the article, redrew its diagrams from memory and attempted every exercise.

  • 01. Start Here: What System Design Is and How to Learn It
  • 02. Functional and Non-Functional Requirements
  • 03. How a Web Request Travels
  • 04. API Design
  • 05. Synchronous vs Asynchronous Communication
  • 06. Back-of-the-Envelope Estimation
  • 07. Estimating Storage, Bandwidth, Cache Size and Server Count
  • 08. Load Balancers
  • 09. Caching
  • 10. CDNs and Object Storage
  • 11. Message Queues, Pub/Sub and Event Streams
  • 12. Relational Databases and Data Modeling
  • 13. Database Indexes
  • 14. Transactions and Concurrency Control
  • 15. Database Replication
  • 16. Sharding and Partitioning
  • 17. SQL vs NoSQL
  • 18. Why Distributed Systems Are Hard
  • 19. CAP Theorem and Consistency Models
  • 20. Idempotency, Retries and Delivery Guarantees
  • 21. Distributed Transactions
  • 22. Distributed Locks and Leader Election
  • 23. Fault Tolerance
  • 24. High Availability and Disaster Recovery
  • 25. Observability
  • 26. Monolith vs Microservices
  • 27. Event-Driven Architecture, CQRS and Event Sourcing
  • 28. Security in System Design
  • 29. The System Design Interview Framework
  • 30. Design a URL Shortener (and Pastebin)
  • 31. Design a Rate Limiter
  • 32. Design a Distributed Cache
  • 33. Design a Notification System
  • 34. Design a Chat System
  • 35. Design a News Feed
  • 36. Design Search Autocomplete
  • 37. Design a Job Scheduler
  • 38. Design a Ticket Booking System
  • 39. Design a Payment System
  • 40. Design a Video Streaming Platform
  • 41. Design a Ride-Hailing System
  • 42. Design a Food Delivery Platform
  • 43. Design an E-Commerce System
  • 44. Design a Web Search Engine
  • 45. Practice Plan and Job-Ready Checklist

Exercises

#

Exercise 1

Why is it here?

#

A classmate shows you this design for a college club's event sign-up page, used by about 300 students a year:

Code
Users -> CDN -> Load balancer -> 6 app servers -> Redis cache -> PostgreSQL                                     |                                     v                                   Kafka -> 3 worker services

For each component, ask "why is this here?" Which would you keep, and what would you replace the design with?

Exercise 2: Which phase?

#

Assign each statement to one of the seven phases (Clarify, Estimate, Interface, Data, Baseline, Scale, Harden):

  1. "Should users be able to edit a post after publishing it?"
  2. "POST /posts returns 201 Created with the new post's id."
  3. "At 5,000 reads per second, one database will struggle, so let's add read replicas."
  4. "If the cache goes down, every read hits the database. Can it take that load?"
  5. "About 2 million posts a day at 1 KB each is roughly 2 GB a day."
  6. "A post has an id, an author id, text and a created-at time; we read posts by author, newest first."

Exercise 3: Evolve the design

#

Pixly is at Stage 3 (load balancer, three app servers, one database). Users complain that the home page takes three seconds to load at peak time. Monitoring shows the database CPU at 95%, mostly from the same few queries for popular profiles. Application server CPU is at 30%. What do you add, what problem does it solve, and what new problem does it create?

Exercise 4: HLD or LLD?

#

Classify each interview question as high-level design or low-level design:

  1. "Design the classes for a parking-lot system."
  2. "Design a system that sends 50 million push notifications a day."
  3. "Design a rate limiter that works across 40 API servers."
  4. "Which design pattern would you use to add new payment methods without changing existing code?"
Show solutionHide solution

At 300 users a year, the traffic is tiny: even if everyone signs up in the same hour, that is a handful of requests per minute. Go through each component:

  • CDN: there are almost no static assets worth caching globally, and users are on one campus. Not needed.
  • Load balancer and 6 app servers: one small server handles this load easily. You might keep two servers behind a load balancer if the page must never be down during sign-up week, but that is an availability decision, not a load decision.
  • Redis cache: the database is not under any read pressure. A cache adds a second copy of data that can go stale. Not needed.
  • Kafka and 3 workers: is there any slow background work? Perhaps a confirmation email. A simple background job in the same application, or a managed email service called directly, is enough.

A reasonable design: one application server (or a managed platform that runs it), one managed PostgreSQL database with automated backups, and an email service. If the club wants high availability during sign-up week, run two app instances behind a managed load balancer.

The lesson: every component costs money, operations work and new failure modes. Add it only when a requirement needs it.

Exercise 2

Show solutionHide solution
  1. Clarify. It decides what the system must do (a functional requirement).
  2. Interface. It defines an API and its response.
  3. Scale. It identifies a bottleneck and fixes it.
  4. Harden. It asks about a failure and its effect on another component.
  5. Estimate. It turns usage into storage numbers.
  6. Data. It defines an entity and, importantly, its access pattern (by author, newest first), which will drive the choice of keys and indexes.

If statement 6 had said "so we'll use Cassandra", it would be jumping ahead. The access pattern comes first; the storage choice follows.

Exercise 3

Show solutionHide solution

The symptom is high database CPU caused by repeated reads of the same popular data, while the application servers have spare capacity. Adding more application servers would not help, because they would send even more queries to the same database.

Add a cache (for example Redis) in front of the database for profile data. The application first looks in the cache; on a miss it reads the database and stores the result in the cache with an expiry time. Popular profiles will then be served from memory, which removes most of the repeated queries and lowers latency.

New problems it creates:

  • Staleness. If a user changes their profile picture, the cache may keep showing the old one until the entry expires or is deleted. You need an invalidation plan (article 09).
  • A new failure mode. If the cache fails, all those reads go back to the database at once, which was already struggling. You need to know whether the database can survive that, or protect it (articles 09 and 23).

You might also check whether the queries are missing an index (article 13), which is cheaper than any new component.

Exercise 4

Show solutionHide solution
  1. LLD. It asks for classes and their relationships.
  2. HLD. It is about throughput, queues, providers and retries across many machines.
  3. HLD. The difficulty is sharing limits across machines, which is a distributed-systems problem (article 31).
  4. LLD. It is about code structure (this is the Strategy pattern).

Some interviews mix the two, for example "design a rate limiter, then write the token-bucket class". This course covers the high-level part and the small amount of code needed to make an idea concrete.

Where to go next

#
  • Guide · Technology

    How to Learn Programming When AI Can Already Write Code

  • Guide · Technology

    Start Here: Your Roadmap from Zero to Job-Ready DSA

  • Guide · Career

    A LinkedIn Profile That Gets Recruiter Messages