What Is System Design? A Complete Introduction
Understand what system design is, why it matters for engineers, the core building blocks of scalable systems, and how to approach system design interviews.
What you'll learn
- ✓What system design is and why every engineer needs it
- ✓The core building blocks: load balancers, caches, databases, queues
- ✓How real companies like Netflix and Uber scale their systems
- ✓The difference between horizontal and vertical scaling
- ✓How to think about system design interviews
- ✓A roadmap for learning system design from scratch
Prerequisites
- •Basic programming knowledge in any language
- •No prior system design experience required
🏗️ System Design — the skill that separates junior engineers from senior ones.
Why system design matters
Imagine you have built a to-do app that works perfectly on your laptop. It handles 10 users without breaking a sweat. Now imagine that 10 million people want to use it tomorrow. What breaks?
Everything.
Your single database cannot handle 10 million reads per second. Your single server runs out of memory. Your application crashes when two users try to edit the same item at the same time. Users in Tokyo experience 3-second delays because your server is in Virginia. A single server failure takes down the entire application.
System design is the discipline of building software that works reliably at scale. It is the difference between a weekend project and a production system that serves millions of users 24 hours a day, 7 days a week, without going down.
Every major technology company — Google, Amazon, Netflix, Uber, Meta — has dedicated teams of engineers whose primary job is designing systems that handle massive scale. When Google processes 8.5 billion searches per day, or Netflix streams video to 250 million subscribers simultaneously, or WhatsApp delivers 100 billion messages daily, those numbers are not accidents. They are the result of deliberate, thoughtful system design.
What system design actually is
At its core, system design is the process of defining the architecture, components, and interactions of a system to satisfy a set of requirements. It answers questions like:
- How do we store data so it can be retrieved quickly?
- How do we handle 100,000 users hitting the system at the same time?
- What happens when a server crashes? Does the whole system go down?
- How do we keep data consistent when it is stored in multiple places?
- How do we serve users in different countries with low latency?
System design sits at the intersection of software engineering, distributed systems, networking, and databases. It is not about writing code — it is about deciding what to build, where to put it, and how the pieces connect.
Think of it like architecture in the physical world. A software engineer is like a carpenter who can build a beautiful cabinet. A system designer is like an architect who plans an entire skyscraper — deciding where the elevators go, how much weight the foundation can support, how water flows through every floor, and what happens during an earthquake. Both skills are essential, but they operate at different levels of abstraction.
The building blocks
Every large-scale system is assembled from the same fundamental building blocks. Understanding these components is the foundation of system design.
Clients and servers
The most basic architecture is client-server. A client (your browser, mobile app, or API consumer) sends a request to a server, which processes it and sends back a response. This is how the web works at its simplest level.
But a single server has limits. It can only handle so many simultaneous connections, store so much data, and perform so many computations per second. When you hit those limits, you need the other building blocks.
Load balancers: distributing traffic
When one server is not enough, you add more servers. But how do users know which server to connect to? That is where a load balancer comes in.
A load balancer sits in front of your servers and distributes incoming requests across them. Think of it like a restaurant host who seats guests at different tables to prevent any one waiter from being overwhelmed.
Common load balancing strategies include:
| Strategy | How it works | Best for |
|---|---|---|
| Round robin | Sends requests to servers in rotation: 1, 2, 3, 1, 2, 3… | Equal-capacity servers |
| Least connections | Sends to the server with the fewest active connections | Varying request complexity |
| Weighted | Sends more requests to more powerful servers | Mixed hardware |
| IP hash | Same user always goes to the same server | Session affinity |
Load balancers also perform health checks — they periodically ping each server to make sure it is alive. If a server crashes, the load balancer automatically stops sending traffic to it and routes requests to the healthy servers. This is how systems survive hardware failures without users noticing.
Databases: where data lives
Every system needs to store data. The choice of database is one of the most important decisions in system design because it affects performance, scalability, and reliability.
Relational databases (PostgreSQL, MySQL) store data in tables with rows and columns, enforce schemas, and support complex queries with SQL. They guarantee ACID properties — Atomicity, Consistency, Isolation, Durability — which means your data stays correct even when things go wrong. Think of them like a well-organized filing cabinet with strict rules about where things go.
NoSQL databases come in several flavors:
- Document stores (MongoDB) — store data as flexible JSON-like documents. Great when your data shape varies.
- Key-value stores (Redis) — simple lookup by key, extremely fast. Used for caching and session storage.
- Wide-column stores (Cassandra) — handle massive write volumes across many servers. Used by Netflix, Instagram, and Discord.
- Graph databases (Neo4j) — store relationships between entities. Used for social networks and recommendation engines.
The choice is never “SQL vs NoSQL” in absolute terms — it depends on your specific access patterns, consistency requirements, and scale needs. Most large systems use multiple databases for different purposes. This is called polyglot persistence.
Caching: speed through memory
Databases store data reliably, but reading from disk is slow. Caching stores frequently accessed data in memory (RAM) so it can be retrieved in microseconds instead of milliseconds.
A cache is like a sticky note on your desk. Instead of walking to the filing cabinet every time you need a phone number you call ten times a day, you write it on a sticky note. The filing cabinet (database) is the source of truth, but the sticky note (cache) is much faster to access.
Redis and Memcached are the most popular caching solutions. Common caching strategies include:
- Cache-aside — the application checks the cache first. If the data is not there (a “cache miss”), it reads from the database and puts the result in the cache.
- Write-through — every write goes to both the cache and the database simultaneously.
- Write-behind — writes go to the cache immediately, and the cache asynchronously writes to the database later.
Caching introduces a trade-off: stale data. If you update the database but the cache still holds the old value, users see outdated information. Managing this trade-off — choosing how long data stays cached, when to invalidate it, and what consistency level is acceptable — is a core system design skill.
Message queues: decoupling components
In a synchronous system, Component A calls Component B directly and waits for a response. If B is slow or down, A is stuck. A message queue decouples them.
Think of it like leaving a voicemail. Instead of calling someone and waiting for them to pick up (synchronous), you leave a message and they process it when they are ready (asynchronous). The voicemail box (queue) ensures the message is not lost even if the recipient is temporarily unavailable.
Apache Kafka, RabbitMQ, and Amazon SQS are popular message queues. They enable:
- Asynchronous processing — the user gets an immediate response while heavy work happens in the background
- Load leveling — absorb traffic spikes without overwhelming downstream services
- Decoupling — services can evolve independently without tight dependencies
CDNs: serving users worldwide
A Content Delivery Network (CDN) is a network of servers distributed across the globe that cache and serve content from locations close to users. When a user in Mumbai requests an image, it comes from a server in Mumbai, not from your data center in Virginia.
CDNs like Cloudflare, AWS CloudFront, and Akamai reduce latency dramatically. Netflix, for example, built its own CDN called Open Connect that caches popular content directly inside ISP networks, so a Netflix stream often travels less than a mile from your router.
Scaling: how systems grow
When your system needs to handle more load, you have two fundamental approaches.
Vertical scaling (scale up)
Add more power to your existing server — more CPU, more RAM, more disk. This is the simplest approach and works well up to a point. But there is an upper limit (you cannot make one server infinitely powerful), it creates a single point of failure, and the cost increases exponentially.
Horizontal scaling (scale out)
Add more servers. Instead of one powerful machine, you use many smaller machines working together. This is how every major internet company scales. It has no practical upper limit, provides redundancy (if one server dies, others continue), and is cost-effective (commodity hardware is cheap).
The trade-off is complexity. With multiple servers, you need to handle:
- Data consistency — how do you ensure all servers see the same data?
- State management — where does user session data live if requests go to different servers?
- Coordination — how do servers agree on who handles what?
Most real-world systems use a combination: they scale vertically until they hit a wall, then scale horizontally.
How real companies scale
Understanding how real companies design their systems brings these concepts to life.
Netflix: 250M+ subscribers, zero downtime
Netflix’s architecture is a masterclass in system design. Their system handles:
- 250 million subscribers across 190+ countries
- Thousands of titles, each in dozens of resolutions and audio formats
- Peak traffic during popular releases that would crash most systems
Key design decisions:
- Microservices architecture — over 1,000 independent services, each owned by a small team
- Open Connect CDN — their custom CDN caches content at ISP locations worldwide
- Chaos engineering — they intentionally kill servers in production (Chaos Monkey) to ensure the system handles failures gracefully
- Multiple databases — Cassandra for distributed data, ElasticSearch for search, EVCache for caching
Uber: real-time at global scale
Uber must match riders with drivers in real time, calculate ETAs, compute surge pricing, and process payments — all in milliseconds. Their system:
- Uses H3 hexagonal grid for geospatial indexing — dividing the earth into hexagons for efficient location queries
- Processes over 1 million events per second through Apache Kafka
- Migrated from a Python monolith to Go microservices for better performance
- Uses Redis for real-time caching of driver locations
WhatsApp: 2 billion users, 50 engineers
WhatsApp’s story is remarkable because they served 2 billion users with an engineering team of roughly 50 people. Their secret:
- Erlang/BEAM VM — chosen for its ability to handle millions of concurrent connections per server
- FreeBSD — tuned to handle 2 million TCP connections per server
- Simplicity — they resisted adding features that would complicate the architecture
- Store-and-forward — messages are stored on the server until the recipient comes online
The CAP theorem: you cannot have everything
One of the most important theoretical foundations of system design is the CAP theorem, which states that a distributed system can only guarantee two of three properties:
- Consistency — every read returns the most recent write
- Availability — every request gets a response (even if it is not the most recent data)
- Partition tolerance — the system continues operating despite network failures between servers
Since network partitions always happen in distributed systems, you are really choosing between consistency and availability during a partition:
- CP systems (MongoDB, HBase) — return an error or timeout rather than stale data
- AP systems (Cassandra, DynamoDB) — always respond, but may return stale data
Neither is universally better — the choice depends on your use case. A banking system needs consistency (you cannot show a wrong balance). A social media feed can tolerate eventual consistency (seeing a post 2 seconds late is fine).
System design interviews
System design interviews are a critical part of the hiring process at senior engineering levels. They test your ability to think at scale, make trade-offs, and communicate design decisions clearly.
A typical system design interview looks like this:
-
Requirements gathering (3-5 min) — ask clarifying questions. How many users? What are the core features? What are the non-functional requirements (latency, availability)?
-
High-level design (10-15 min) — sketch the major components: clients, load balancers, application servers, databases, caches, message queues.
-
Deep dive (10-15 min) — the interviewer picks one or two areas to explore in depth. Database schema? Caching strategy? How to handle failover?
-
Trade-offs and bottlenecks (5 min) — identify potential problems and how you would address them. What is the single point of failure? Where is the bottleneck?
The most common mistake is jumping into the solution without understanding the requirements. The second most common mistake is trying to design a perfect system instead of making clear, justified trade-offs.
Classic system design interview questions
| Question | Key concepts tested |
|---|---|
| Design a URL shortener | Hashing, database design, read-heavy scaling |
| Design a chat application | WebSockets, message queues, presence detection |
| Design a news feed | Fanout strategies, caching, ranking algorithms |
| Design a rate limiter | Token bucket, sliding window, distributed counting |
| Design a notification system | Message queues, multi-channel delivery, fan-out |
| Design a web crawler | BFS traversal, URL frontier, politeness policies |
Your learning roadmap
System design is a broad field. Here is a practical order for learning:
Phase 1: Foundations
- Networking Fundamentals — TCP/IP, HTTP, DNS, TLS
- SQL vs NoSQL Databases — when to use each
- Caching Strategies — cache-aside, write-through, invalidation
- Load Balancer Design — algorithms, health checks, L4 vs L7
Phase 2: Core patterns 5. Database Replication — leader-follower, quorum 6. Database Sharding — horizontal partitioning 7. CAP Theorem — consistency vs availability 8. Scalability Patterns — horizontal scaling, CQRS
Phase 3: Advanced topics 9. Distributed Systems — consensus, clocks, failure 10. Microservices Architecture — service boundaries, communication 11. API Design — REST, GraphQL, gRPC
Phase 4: Real-world case studies 12. Netflix Architecture — microservices, CDN, chaos engineering 13. Uber Architecture — geospatial, real-time matching 14. WhatsApp Architecture — Erlang, 2B users, 50 engineers
Each of these articles is available in the System Design section of this site. Start from the top and work your way down — each article builds on the concepts from the previous ones.
Related articles
- System Design Caching Strategies in System Design: A Practical Guide
Compare cache-aside, read-through, write-through, write-behind, and refresh-ahead. Learn when each strategy fits, what consistency you give up, and how to choose for interviews.
- Data Engineering Data Engineering Interview Prep — What to Expect and How to Win
Prepare for data engineering interviews: SQL deep dives, Python coding, system design, data modeling, behavioral questions, and take-home project tips.
- Career Software Engineer Interview Prep: A Starter Plan
A realistic plan for software engineer interview prep — what the loops look like, where to study, how to practice deliberately, mock interviews, talking while coding, and behavioral STAR.
- System Design API Design Best Practices: REST, GraphQL, gRPC, and Beyond
Master API design with REST principles, GraphQL trade-offs, gRPC for microservices, pagination strategies, rate limiting, and authentication patterns. Learn why Stripe's API is the gold standard.