System Design
Learn System Design
Introduction to System Design
How to Learn System Design?
Network Essentials
HTTP vs. HTTPS
TCP vs. UDP
HTTP: 1.0 vs. 1.1 vs 2.0 vs. 3.0
URL vs. URI vs. URN
What Happens When You Type a URL into the Browser
Flashcards Review
Chapter Assessment
Long-Polling vs. WebSockets vs. Server-Sent Events
Introduction to Real-Time Communication
What is Long-Polling?
What is WebSocket?
What are Server-Sent Events?
Difference Between Long-Polling, WebSockets, and Server-Sent Events
Flashcards Review
Chapter Assessment
Domain Name System (DNS)
Introduction to DNS
DNS Resolution Process
DNS Load Balancing and High Availability
Flashcards Review
Chapter Assessment
Proxies
What is a Proxy Server?
Uses of Proxies
VPN vs. Proxy Server
Flashcards Review
Chapter Assessment
Load Balancing
Introduction to Load Balancing
Load Balancing Algorithms
Uses of Load Balancing
Load Balancer Types
Stateless vs. Stateful Load Balancing
High Availability and Fault Tolerance
Scalability and Performance
Challenges of Load Balancers
Flashcards Review
Chapter Assessment
API Gateway
Introduction to API Gateway
Usage of API gateway
Advantages and disadvantages of using API gateway
Flashcards Review
Chapter Assessment
API Design
What Is an API?
What Are REST APIs?
Resources, Not Actions
HTTP Methods and Their Semantics
URL Design
Request and Response Shapes
Status Codes and Error Design
Pagination from the Consumer's View
Idempotency Keys
Versioning and Backward Compatibility
Concurrency and Conditional Requests
REST vs gRPC vs GraphQL
Flashcards Review
Chapter Assessment
Rate Limiting and Throttling
What Is Rate Limiting
Rate Limiting Algorithms
Distributed Rate Limiting
Rate Limiting in Practice
Flashcards Review
Chapter Assessment
Caching
Introduction to Caching
Why is Caching Important?
Types of Caching
Cache Replacement Policies
Cache Invalidation
Cache Read Strategies
Cache Coherence and Consistency Models
Caching Challenges
Cache Performance Metrics
Flashcards Review
Chapter Assessment
CDN
What is CDN?
Origin Server vs. Edge Server
CDN Architecture
Push CDN vs. Pull CDN
Flashcards Review
Chapter Assessment
Data Partitioning
Introduction to Data Partitioning
Partitioning Methods
Data Sharding Techniques
Benefits of Data Partitioning
Common Problems Associated with Data Partitioning
Flashcards Review
Chapter Assessment
Redundancy and Replication
What is Redundancy?
What is Replication?
Replication Methods
Data Backup vs. Disaster Recovery
Flashcards Review
Chapter Assessment
CAP & PACELC Theorems
Introduction to CAP Theorem
Components of CAP Theorem
Trade-offs in CAP Theorem
Examples of CAP Theorem in Practice
Beyond CAP Theorem
System Design Trade-offs in Interviews
Flashcards Review
Chapter Assessment
Databases (SQL vs. NoSQL)
Introduction to Databases
SQL Databases
NoSQL Databases
SQL vs. NoSQL
ACID vs BASE Properties
Real-World Examples and Case Studies
SQL Normalization and Denormalization
In-Memory Database vs. On-Disk Database
Data Replication vs. Data Mirroring
Database Federation
Flashcards Review
Chapter Assessment
Indexes
What are Indexes?
How a B-Tree Index Works
Types of Indexes
B-Tree vs. LSM Tree
Indexes in Distributed Systems
Flashcards Review
Chapter Assessment
Bloom Filters
Introduction to Bloom Filters
Benefits & Limitations of Bloom Filters
Variants and Extensions of Bloom Filters
Applications of Bloom Filters
Flashcards Review
Chapter Assessment
Quorum
Why Quorum?
What is Quorum?
Flashcards Review
Chapter Assessment
Leader and Follower
What is Leader and Follower Pattern?
Flashcards Review
Chapter Assessment
Heartbeat
What is Heartbeat?
Flashcards Review
Chapter Assessment
Checksum
What is Checksum?
Uses of Checksum
Flashcards Review
Chapter Assessment
Distributed Messaging System
Introduction to Messaging System
Introduction to Kafka
Messaging patterns
Popular Messaging Queue Systems
RabbitMQ vs. Kafka vs. ActiveMQ
Scalability and Performance
Flashcards Review
Chapter Assessment
Distributed File Systems
What is a Distributed File System?
Architecture of a Distributed File System
Key Components of a DFS
Flashcards Review
Chapter Assessment
Security
What is Security and Privacy?
What is Authentication?
What is Authorization?
Authentication vs. Authorization
OAuth vs. JWT for Authentication
What is Encryption?
What are DDoS Attacks?
Flashcards Review
Chapter Assessment
Misc Concepts
Batch Processing vs. Stream Processing
XML vs. JSON
Synchronous vs. Asynchronous Communication
Push vs. Pull Notification Systems
Microservices vs. Serverless Architecture
Message Queues vs. Service Bus
Stateful vs. Stateless Architecture
Event-Driven vs. Polling Architecture
Flashcards Review
Chapter Assessment
Quiz - System Design Fundamentals
Quiz
System Design Trade-offs
Importance of Discussing Trade-offs
Strong vs Eventual Consistency
Latency vs Throughput
ACID vs BASE Properties in Databases
Read-Through vs Write-Through Cache
Batch Processing vs Stream Processing
Load Balancer vs. API Gateway
API Gateway vs Direct Service Exposure
Proxy vs. Reverse Proxy
API Gateway vs. Reverse Proxy
SQL vs. NoSQL
Primary-Replica vs Peer-to-Peer Replication
Data Compression vs Data Deduplication
Server-Side Caching vs Client-Side Caching
REST vs RPC
Polling vs. Long-Polling vs. WebSockets vs. Webhooks
CDN Usage vs Direct Server Serving
Serverless Architecture vs Traditional Server-based
Stateful vs Stateless Architecture
Hybrid Cloud Storage vs All-Cloud Storage
Token Bucket vs Leaky Bucket
Read Heavy vs Write Heavy System
Quiz
How to Approach a System Design Interview
System Design Interviews - A step by step guide
Functional vs. Non-functional Requirements
What are Back-of-the-Envelope Estimations?
Things to Avoid During System Design Interview
System Design Master Template
System Design Master Template
Quiz
Designing a URL Shortening Service like TinyURL
Designing a URL Shortening Service like TinyURL
Quiz - Designing URL Shortner
Designing Pastebin
Designing Pastebin
Quiz - Designing Pastebin
Designing Instagram
Designing Instagram
Quiz - Designing Instagram
Designing Dropbox
Designing Dropbox
Quiz - Designing Dropbox
Designing Facebook Messenger
Designing Facebook Messenger
Quiz - Designing Facebook Messenger
Designing Twitter
Designing Twitter
Quiz - Designing Twitter
Designing Youtube or Netflix
Designing Youtube or Netflix
Quiz - Designing Youtube
Designing Typeahead Suggestion
Designing Typeahead Suggestion
Quiz - Designing Typeahead Suggestion
Designing an API Rate Limiter
Designing an API Rate Limiter
Quiz - Designing an API Rate Limiter
Designing Twitter Search
Designing Twitter Search
Quiz - Designing Twitter Search
Designing a Web Crawler
Designing a Web Crawler
Quiz - Designing a Web Crawler
Designing Facebook’s Newsfeed
Designing Facebook’s Newsfeed
Quiz - Designing Facebook’s Newsfeed
Designing Yelp or Nearby Friends
Designing Yelp or Nearby Friends
Quiz - Designing Yelp or Nearby Friends
Designing Uber backend
Designing Uber backend
Quiz - Designing Uber backend
Designing Ticketmaster
Designing Ticketmaster
Quiz - Designing Ticketmaster
Dynamo: How to design a key value store?
Dynamo: Introduction
High-Level Architecture
Data Partitioning
Replication
Vector Clocks and Conflicting Data
The Life of Dynamo’s put() & get() Operations
Anti-entropy Through Merkle Trees
Gossip Protocol
Dynamo Characteristics and Criticism
Summary: Dynamo
Quiz: Dynamo
Mock Interview: Dynamo
Designing YouTube Likes Counter (medium)
YouTube Likes Counter
Quiz
Cassandra: How to Design a Wide-column NoSQL Database?
Cassandra: Introduction
High-level Architecture
Replication
Cassandra Consistency Levels
Gossiper
Anatomy of Cassandra's Write Operation
Anatomy of Cassandra's Read Operation
Compaction
Tombstones
Summary: Cassandra
Quiz: Cassandra
Mock Interview: Cassandra
Kafka: How to Design a Distributed Messaging System?
Messaging Systems: Introduction
Kafka: Introduction
High-level Architecture
Kafka: Deep Dive
Consumer Groups
Kafka Workflow
Role of ZooKeeper
Controller Broker
Kafka Delivery Semantics
Kafka Characteristics
Summary: Kafka
Quiz: Kafka
Mock Interview: Kafka
Chubby: How to Design a Distributed Locking Service?
Chubby: Introduction
High-level Architecture
Design Rationale
How Chubby Works
File, Directories, and Handles
Locks, Sequencers, and Lock-delays
Sessions and Events
Master Election and Chubby Events
Caching
Database
Scaling Chubby
Summary: Chubby
Quiz: Chubby
Mock Interview: Chubby
HDFS: How to Design File Storage System?
Hadoop Distributed File System: Introduction
High-level Architecture
Deep Dive
Anatomy of a Read Operation
Anatomy of a Write Operation
Data Integrity & Caching
Fault Tolerance
HDFS High Availability (HA)
HDFS Characteristics
Summary: HDFS
Quiz: HDFS
Mock Interview: HDFS
GFS: How to Design a Distributed File System Storage?
Google File System: Introduction
High-level Architecture
Single Master and Large Chunk Size
Metadata
Master Operations
Anatomy of a Read Operation
Anatomy of a Write Operation
Anatomy of an Append Operation
GFS Consistency Model and Snapshotting
Fault Tolerance, High Availability, and Data Integrity
Garbage Collection
Criticism on GFS
Summary: GFS
Quiz: GFS
Mock Interview: GFS
BigTable: How to Design a Wide Column Storage System?
BigTable: Introduction
BigTable Data Model
System APIs
Partitioning and High-level Architecture
SSTable
GFS and Chubby
Bigtable Components
Working with Tablets
The Life of BigTable's Read & Write Operations
Fault Tolerance and Compaction
BigTable Refinements
BigTable Characteristics
Summary: BigTable
Quiz: BigTable
Mock Interview: BigTable
Designing Reddit (medium)
Design Reddit
Quiz
Designing Notification Service (medium)
Designing a Notification System
Quiz
Design Google Calendar (medium)
Design Google calendar (Medium)
Quiz
Design a Recommendation System (medium)
Design a Recommendation System for Netflix
Quiz
Designing Gmail (medium)
Design Gmail
Quiz
Designing Google News (medium)
Design Google News, a Global News Aggregator System (Medium)
Quiz
Designing Unique ID Generator (medium)
Design Unique ID Generator (Easy)
Quiz
Designing Code Judging System (medium)
Design Code Judging System like LeetCode (Medium)
Quiz
Designing Payment System (hard)
Design Payment System
Quiz
Designing Flash Sale System (hard)
Design a Flash Sale for an E-commerce Site (Hard)
Quiz
Designing Reminder Alert System (hard)
Design a Reminder Alert System
Quiz
System Design Patterns
Introduction: System Design Patterns
1. Bloom Filters
2. Consistent Hashing
3. Quorum
4. Leader and Follower
5. Write-ahead Log
6. Segmented Log
7. High-Water Mark
8. Lease
9. Heartbeat
10. Gossip Protocol
11. Phi Accrual Failure Detection
12. Split Brain
13. Fencing
14. Checksum
15. Vector Clocks
16. CAP Theorem
17. PACELC Theorem
18. Hinted Handoff
19. Read Repair
20. Merkle Trees
Quiz
Concurrency and Coordination
consistency models
distributed systems
availability
Two people want the last seat on a flight. They both tap "Book" at the same moment, on different phones. Both screens say "Booked!" The airline now has two passengers and one seat.
Nothing crashed, and both requests ran correct code. The problem is that they ran at the same time, on the same data.
This lesson answers three questions. How do we stop work that runs at the same time from damaging shared data? How do many machines agree on things, like which one is in charge? And when data has copies in many places, what can a reader expect to see?
What Concurrency Means
Concurrency means many tasks are in progress at the same time. A web server handles thousands of requests at once. A database serves many users at once. In a distributed system, many machines also work on the same data.
A running program is called a process. A process can run several threads, which are smaller units of work that share the same memory. Everything in this lesson applies to both.
Concurrency is useful because it lets one system serve many users. It also creates a new kind of bug.
Race Conditions
A race condition is a bug where the result depends on the exact timing of tasks that run at the same time.
Here is a simple example. A post has 100 likes. Two users like it at the same moment, and two servers handle the requests.
- Server A reads the like count: 100.
- Server B reads the like count: 100.
- Server A adds 1 and writes 101.
- Server B adds 1 and writes 101.
Two likes were added, but the count only went up by one. Server B wrote over Server A's change. This is called a lost update.
This bug is hard to find because it does not happen every time. If Server B had read the count after Server A wrote 101, the result would be correct. Race conditions often appear only under heavy traffic.
Concurrency Control
Concurrency control manages access to shared resources or data when many processes run at the same time. Its goal is to let them work together without conflicts or inconsistent data.
There are three main techniques: locking, optimistic concurrency control, and transactional memory.
Locking
A lock restricts access to a shared resource, so that only one process can use it at a time. A process takes the lock, does its work, and releases the lock. Any other process that wants the resource must wait.
In the like-count example, Server A takes a lock on the post, reads 100, and writes 101. Server B waits. Then Server B takes the lock, reads 101, and writes 102. The result is correct.
Locking is simple and safe, but it has two costs.
- Waiting. While one process holds a lock, the other processes that need it must wait. A lock held for a long time slows the whole system.
- Deadlock. A deadlock happens when two processes each wait for a lock that the other one holds. Process 1 holds lock X and waits for lock Y. Process 2 holds lock Y and waits for lock X. Neither can continue.
A common way to prevent deadlock is to always take locks in the same order. Another way is to stop waiting and retry if a lock is not free after a short time.
Optimistic Concurrency Control
Optimistic concurrency control assumes that conflicts are rare. Processes run freely, without locks. Before saving, each process checks whether someone else changed the data. If there was a conflict, the process detects it and tries again.
A common way to check is a version number stored with the data. Here is how it works.
- Server A and Server B both read the post. Its like count is 100, and its version is 7.
- Server A writes 101, but only if the version is still 7. It is, so the write succeeds, and the version becomes 8.
- Server B tries to write 101, but only if the version is still 7. The version is now 8, so the write fails.
- Server B reads the post again, sees 101 and version 8, and writes 102.
When conflicts really are rare, nobody waits, and the system is fast. When conflicts are common, processes keep failing and retrying, which wastes work. In that case, locking is often the better choice.
| Locking | Optimistic concurrency control | |
|---|---|---|
| Assumption | Conflicts are likely | Conflicts are rare |
| When two processes conflict | The second one waits | The second one retries |
| Main cost | Waiting, and possible deadlock | Repeated work after a conflict |
| Good fit | Booking the last seats on a flight | Editing a user profile |
Transactional Memory
Transactional memory groups several operations into one transaction that runs atomically. Atomic means that all the operations happen, or none of them do. No other process can see the work half done.
For example, moving money between two accounts takes two steps. The app subtracts the money from one account and adds it to the other. When they run as one transaction, the two steps cannot be split. No other process ever sees the money missing from both accounts.
Database transactions use the same idea. The ACID vs. BASE lesson explains them.
Synchronization
Synchronization coordinates the execution of processes or threads, so that the system works correctly. It controls the order and timing of their work.
There are four common tools.
Mutexes. A mutex (mutual exclusion lock) lets exactly one thread at a time use a resource. A thread locks the mutex, does its work, and unlocks it. Every other thread that wants the resource waits until then. This is the most common form of the lock described above.
Semaphores. A semaphore limits how many threads can use a pool of resources at the same time. It keeps a counter of free slots. Each thread that enters takes one slot. When no slots are free, the next thread waits until one is released.
A database connection pool is the standard example. Suppose an app has 20 database connections, guarded by a semaphore with 20 slots. The first 20 requests get a connection at once. The 21st request waits until one of them finishes. A semaphore with only one slot works like a mutex.
Condition variables. A condition variable lets a thread sleep until a condition becomes true. The classic example is a worker waiting for a queue to have items. The worker does not check the queue again and again. It sleeps, and the thread that adds work to the queue wakes the worker up.
Barriers. A barrier holds threads at a point until all of them arrive, and then lets them all continue. A job that runs in phases uses one. Every worker must finish phase one before any worker starts phase two.
Concurrency Control vs. Synchronization
The two ideas are easy to mix up because both deal with work that runs at the same time.
Concurrency control is about access. It manages who can use a shared resource, and it prevents conflicts when two processes want to change the same data.
Synchronization is about timing and order. It makes sure certain work happens before other work, and that processes do not interfere with each other.
One asks, "May you use this data now?" The other asks, "Is it your turn yet?"
| Concurrency control | Synchronization | |
|---|---|---|
| Main question | Who may change the data? | In what order does work run? |
| Tools | Locking, optimistic control, transactional memory | Mutexes, semaphores, condition variables, barriers |
| Problem it prevents | Conflicting changes to data | Work running in the wrong order |
Coordination Services
Locks and semaphores are easy to use when all threads share one machine's memory. Across many machines, it is much harder. The machines share no memory. Messages over the network can be slow or lost. And any machine can crash in the middle of its work.
Coordination services are specialized tools that handle these hard problems for a distributed system. They provide ready-made solutions for four common tasks.
- Configuration management. All servers read the same settings from one place. When a setting changes, every server learns about it.
- Service discovery. A server finds the addresses of healthy instances of another service. For example, the order service asks where the payment service is running right now.
- Leader election. A group of servers picks exactly one of them as the leader, which is the server that makes decisions for the group. If the leader crashes, the group picks a new one.
- Distributed locking. Processes on different machines share one lock. The lock usually has an expiry time, so it is released if the holder crashes.
The best-known coordination services are Apache ZooKeeper, etcd, and Consul.
A coordination service is itself a small cluster, usually of three or five nodes. A change is accepted only when a majority of the nodes agree. That majority is called a quorum. So the service keeps working even if one node fails. The quorum and leader and follower chapters explain how this works.
Why not build these features yourself? Each one is hard to get right. Small mistakes often cause failures that appear only under heavy load or during a network problem. So teams use a tested service instead.
Consistency Models
Many distributed systems keep copies of the same data on several servers. Each copy is called a replica. When data changes on one replica, the other replicas do not change at the same instant.
A consistency model is the promise a system makes about when a change made in one place becomes visible in another. Every model answers one question: after someone writes something, who may still see the old version, and for how long?
One example, used throughout. Sarah posts "Got the job!" on a social app. The app keeps replicas in several regions. Her friends Raj and Mia read the post from different regions. Each model below says something different about what Raj and Mia may see.
What One Reader Is Promised
These models make a promise to one person. They say nothing about what anyone else sees.
Eventual consistency. Raj sees the post after two seconds, and Mia sees it after ten. Both see it in the end, but there is no promise about when. This is the weakest common model. It also keeps a system fast and available because a replica can answer at once with the data it already has.
Monotonic read consistency. Once Raj has seen the post, it never disappears for him. Without this promise, his next refresh might reach a replica that does not have the post yet. The post would vanish and then come back.
Read-your-writes consistency. Sarah always sees her own post at once, even while Raj and Mia still cannot. The promise is made only to the person who wrote the data. This is why your own profile change looks instant to you, but takes a moment to reach others.
Session consistency. This is read-your-writes for a whole visit, called a session. Sarah keeps seeing her own post even if the app moves her to a different replica during her visit. A shopping cart that keeps showing its items for one user's whole visit is another example.
What Everyone Agrees On
These models describe the order that all readers see, not the experience of one person.
Causal consistency. Raj replies "Congratulations!" to Sarah's post. Anyone who can see Raj's reply must also be able to see the post it answers. A cause is always visible wherever its effect is visible. Operations that are not related may still appear in different orders in different regions.
Sequential consistency. Sarah posts, and then Mia posts. Every reader sees those two posts in the same order. But the shared order does not have to match the clock. Every reader could see Mia's post first, as long as all readers agree.
Linearizability. This is sequential consistency plus the clock. Every operation is atomic, and it is visible to all nodes the instant it completes. The moment Sarah's post is confirmed, a read from any region returns it. The shared order must match the order in which things really happened.
The difference between the last two models needs a precise example. Sarah's write finishes at 10:00:00. Raj starts a read at 10:00:05 and gets the old version, without the post.
- Sequential consistency allows this, as long as all readers agree on one order in which Raj's read came before Sarah's write.
- Linearizability does not allow this, because Sarah's write had already finished in real time before Raj's read began.
A note on names. You will often see strong consistency listed as its own model. In practice, it means linearizability, and this course treats the two as the same guarantee.
These models do not form one simple ranking from weakest to strongest. The first group makes promises to one reader. The second group sets rules for all readers. But every promise has a cost. A stronger guarantee needs more coordination between replicas. That means slower writes, less availability when the network between replicas fails, or both.
So the right model depends on the operation, not on the whole system. A bank balance may need linearizability, while a news feed can be eventually consistent. One system often uses different models for different data. The CAP theorem chapter explains this trade-off.
Key Takeaways
- A race condition is a bug where the result depends on the timing of tasks that run at the same time. A lost update is a common example.
- Concurrency control manages access to shared data. Its techniques are locking, optimistic concurrency control, and transactional memory.
- A lock lets only one process use a resource at a time. It is safe, but others must wait, and deadlocks are possible.
- Optimistic concurrency control assumes conflicts are rare. Processes run freely, and a conflict is detected and fixed with a retry.
- Synchronization coordinates the timing and order of work, using mutexes, semaphores, condition variables, and barriers.
- Coordination services like ZooKeeper, etcd, and Consul provide configuration management, service discovery, leader election, and distributed locking.
- Consistency models range from eventual consistency to linearizability. Stronger promises need more coordination, so choose a model for each operation.
Work that runs at the same time is what lets a system serve many users. Controlling that work is what keeps the data correct. The next lesson, Monitoring and Observability, covers how to find out what such a system is actually doing.
Practice Questions
Try each question first, then open the answer.
1. A product has 10 items in stock. Two servers sell one item each at the same moment. Each server reads the count, subtracts 1, and writes the result, with no lock. What final counts are possible, and which one is correct?
<details> <summary>Show answer</summary>8 is correct, but 9 is also possible. If one server finishes before the other one reads, the second server reads 9 and writes 8. If both servers read 10 before either one writes, both write 9. One sale is then lost. This is a race condition, and a lock or a version check prevents it.
</details>2. Many people edit pages on a wiki, but two people rarely edit the same page at the same time. Should the system use locking or optimistic concurrency control?
<details> <summary>Show answer</summary>Optimistic concurrency control. Conflicts are rare, so most edits succeed on the first try and nobody waits. When a conflict does happen, the second editor reloads the page and makes the change again. With locking, editors would wait for each other, even though conflicts almost never happen.
</details>3. An app has a pool of 10 database connections, and 14 requests arrive at the same time. Which synchronization tool fits, and what happens to the requests?
<details> <summary>Show answer</summary>A semaphore with 10 slots. The first 10 requests each take a slot and a connection. The other 4 requests wait. Each time a request finishes and releases its slot, one waiting request takes it.
</details>4. Three servers run the same code, but only one of them should send the daily report email. If that server crashes, another server should take over. What does the team need, and which tools provide it?
<details> <summary>Show answer</summary>Leader election. The servers use a coordination service like ZooKeeper, etcd, or Consul to pick one leader. Only the leader sends the email. If the leader crashes, the service notices, and the remaining servers pick a new leader.
</details>5. A user changes their profile photo, refreshes the page, and still sees the old photo. It is fine if other users see the old photo for a few seconds. Which consistency model fixes this user's problem at the lowest cost?
<details> <summary>Show answer</summary>Read-your-writes consistency. It promises that the person who made a change sees it at once. Other users may still see the old photo for a short time, under eventual consistency. Linearizability would also fix the problem, but it needs much more coordination between replicas for every user.
</details>Discussion
On This Page