Home› System Design› Complete Guide
Complete Guide

Complete System Design Tutorial

System design interviews separate senior engineers from the rest. This guide covers all 145 system design topics on TheCodeForge — from load balancing and caching to microservices and real-world architecture.

Learning Roadmap
Beginner → Understand client-server, APIs, databases and caching basics
Intermediate → Design scalable services with load balancing and message queues
Advanced → Architect distributed systems, handle failures and interview confidently
145
Topics
9
Beginner
70
Intermediate
66
Advanced
Jump to section
Fundamentals (10)Components (23)Architecture (17)Real World (40)Databases in Design (5)Security (13)Estimation (5)Networking (7)Database Internals (9)Distributed Systems (9)Async & Data Processing (7)

System design is the discipline of choosing which problems to have. Every architecture trades something away — consistency for availability, simplicity for scale, latency for durability — and the mark of a good design is not that it avoids trade-offs but that its author can name the ones they took and why.

That framing also explains why design questions have no answer key. Two competent engineers given the same requirements will produce different systems, and both may be right. What is not negotiable is knowing what each component costs you, because a cache, a queue and a replica all introduce failure modes that did not exist before you added them.

The numbers that decide the architecture

Before any component is chosen, four numbers determine the shape of the answer. How many requests per second, at peak rather than average. The read-to-write ratio. How much data, in total and per item. And how fresh the data must be.

Those four route you to a design almost mechanically. Read-heavy at 100:1 is a caching and replication problem. Write-heavy is a partitioning problem. Data that must be strongly consistent rules out the cheap availability tricks. Data measured in petabytes rules out anything that assumes a single primary.

If the numbers sayThe design is aboutNot about
Read-heavy, tolerant of stalenessCaching, CDN, read replicas, denormalised read modelsSharding — you probably do not need it yet
Write-heavy, high volumePartitioning, append-only storage, batching, back-pressureRead caching, which will not help
Strong consistency requiredA single authoritative writer per key, transactions, consensus where unavoidableMulti-region active-active, which you cannot have cheaply
Spiky, unpredictable loadQueues, autoscaling, graceful degradation, rate limitingProvisioning for peak, which wastes most of the time
Large media or filesObject storage plus CDN, signed URLs, async processingStoring bytes in the primary database

CAP, stated usefully

CAP is routinely misquoted as 'pick two'. The accurate statement is narrower and more useful: when a network partition occurs, a distributed system must choose between remaining available and remaining consistent. Partitions are not optional — they are a property of networks — so the real choice is what happens during one.

The more practically relevant extension is PACELC: even when there is no partition, there is a trade between latency and consistency. Every synchronous replication decision is an instance of it. That is the version worth carrying into design discussions, because partitions are rare and the latency trade is continuous.

In practice'Eventually consistent' is a design decision that needs a number and a user-visible story. How eventual — milliseconds or minutes? And what does a user see in the gap? Read-your-own-writes is usually the one guarantee worth preserving even in an otherwise eventual system.

The patterns worth knowing cold

A short vocabulary covers most designs, and each entry is worth knowing with its cost attached rather than as a name to drop.

PatternBuys youCosts you
Cache-asideLarge read speedup for hot keysStaleness, invalidation logic, thundering herd on expiry
Message queueDecoupling, spike absorption, retriesEventual consistency, ordering questions, a dead-letter queue someone must own
Read replicasRead scale with no application redesignReplication lag — a user may not see their own write
ShardingWrite scale past one primaryNo cross-shard joins or transactions; resharding is painful
Circuit breakerFast failure instead of cascading timeoutsRequires sensible thresholds and a half-open recovery path
Idempotency keysSafe retries for non-idempotent operationsStorage and expiry for the key set
CDNLatency close to the user, origin offloadCache invalidation across edges; not for personalised content

Design for failure, because failure is the normal case

At any real scale something is always broken. The design question is not how to prevent failure but how the system behaves during it. Timeouts on every network call, because a call without a timeout is a resource leak waiting for a slow dependency. Retries with exponential backoff and jitter, because synchronised retries are how a brief blip becomes an outage. Circuit breakers so a slow dependency fails fast instead of consuming every thread.

And graceful degradation: decide in advance which features may be switched off to keep the core working. A product page that renders without recommendations is a far better outcome than one that does not render at all, and that is a design decision made before the incident, not during it.

Frequently Asked Questions

Microservices or a monolith for a new product?
A monolith, almost always. Service boundaries are expensive to move and you do not yet know where they belong. Keep the code modular so the seams are visible, and extract a service when a specific component genuinely needs independent scaling or deployment. Premature microservices buy distributed-systems problems in exchange for organisational benefits you do not yet need.
How do I choose a caching strategy?
By what breaks if the cache is stale. Cache-aside is the default and is right when some staleness is acceptable. Write-through when writes must be immediately visible and you accept the write latency. Write-behind only when losing recent writes on a crash is tolerable — which is rarer than people assume.
When is sharding actually necessary?
When a single primary cannot absorb the write volume or hold the data, and you have already exhausted vertical scaling, indexing, caching and partitioning. It is the most expensive step: cross-shard joins and transactions disappear, and resharding a live system is a project. Reaching for it early is a common and costly mistake.
What is the difference between partitioning and sharding?
Partitioning splits a table within one database instance — the engine manages it and queries are largely unchanged. Sharding splits data across separate instances, which the application or a routing layer must be aware of. Partitioning is an optimisation; sharding is an architecture.
How much should I worry about the thundering herd?
Enough to have a plan for hot keys. When a popular cache entry expires, every concurrent request misses and hits the origin at once. The standard defences are a short randomised jitter on TTLs, a lock so one request refreshes while others serve stale, and refreshing ahead of expiry. It is a small amount of code that prevents a specific, repeatable outage.
Where should someone start with system design?
With one system you already understand, drawn end to end, including what happens when each box fails. Studying designs you have never operated teaches vocabulary; drawing one you have teaches judgement. Then read cases to fill in the components you have not needed yet.

Fundamentals

Components

Architecture

Real World

Databases in Design

Security

Estimation

Networking

Database Internals

Distributed Systems

Async & Data Processing

Interview prep
→System Design Interview
Also Explore
DSA 197 tutorials → DevOps 310 tutorials → Database 144 tutorials → C / C++ 66 tutorials → Cloud 13 tutorials → Observability 10 tutorials →
Start from the beginning

Every tutorial starts with a plain-English analogy — then real code, then interview questions.

Browse System Design Tutorials →