System Design Fundamentals

The building blocks of large-scale systems — caching, sharding, queues, consistency, and the trade-offs behind every design decision.

8 parts · written by Pratik Dhanave. Start with Part 1 →

← All series · All posts

Part 1 · ·12 min read

How to Approach System Design

A repeatable method for designing systems and acing the design interview — clarify requirements, estimate on the back of an envelope, pin down the API and data model, then work high-level to deep-dive to bottleneck, always naming the trade-off.

The opener to a system-design series: a repeatable method rather than a grab-bag of components — clarifying functional vs non-functional requirements, back-of-the-envelope estimation with the latency numbers every engineer should know, and the trade-off-driven design flow.

Part 2 · ·15 min read

Scaling Fundamentals

How systems grow under load — vertical vs horizontal scaling, why statelessness is the real enabler, load balancing from L4 to L7, consistent hashing, read/write scaling, the scale cube, and when the honest answer is "don't scale yet."

How systems grow: vertical vs horizontal scaling, statelessness as the enabler of horizontal scale, load balancing (L4/L7, consistent hashing), read/write scaling with replicas — and knowing when not to scale.

Part 3 · ·15 min read

Caching

The highest-leverage tool for latency and scale — and the source of its hardest problem, invalidation. Where caches live, the patterns for filling them, how they evict, and why keeping them correct is the part that stays hard.

Caching as the highest-leverage latency tool — and its hardest problem: where caches live, the patterns (cache-aside/read-through/write-through/write-behind), eviction, and invalidation including cache stampede, penetration, and hot keys.

Part 4 · ·14 min read

Databases and Storage

Choosing and scaling the data layer without cargo-culting: how to pick relational versus NoSQL by access pattern, why every index is a tax on writes, and why your shard key is the highest-stakes decision you will make.

Choosing and scaling the data layer: relational vs NoSQL by access pattern, indexing (B-tree/hash/LSM), normalization vs denormalization, replication, partitioning/sharding and the shard-key decision, and the distributed-transaction trade-off.

Part 5 · ·15 min read

Consistency, Availability, and Consensus

The theory that governs distributed data, made practical — CAP stated correctly, PACELC, the full consistency spectrum with "what the user sees" examples, quorums, and Raft-style consensus without the proofs.

The theory that governs distributed data, stated correctly: CAP as a partition-time choice (not pick-2-of-3), PACELC, the consistency spectrum with what-the-user-sees examples, quorums, and consensus/Raft at an intuition level.

Part 6 · ·16 min read

Asynchronous Processing and Messaging

How queues, pub/sub, and log-based streaming let systems stay responsive under load — the delivery semantics, ordering rules, backpressure, and outbox patterns that decide whether async saves you or sinks you.

Decoupling with queues and events: message queues vs pub/sub vs log-based streaming, delivery semantics (why exactly-once delivery is a myth — do idempotent processing), ordering, backpressure, the transactional outbox, and dead-letter queues.

Part 7 · ·17 min read

Reliability and Resilience

How to design a system that keeps serving when its parts fail — the vocabulary of availability, the patterns that contain failure, and the Go primitives that make retries, limits, and fallbacks safe rather than dangerous.

Designing systems that survive failure: the nines and SLI/SLO/error budgets, eliminating single points of failure, timeouts and retries with backoff+jitter made safe by idempotency, circuit breakers, rate limiting and load shedding, and graceful degradation.

Part 8 · ·15 min read

Designing a System End to End

The capstone — one problem, a home-timeline feed, designed the whole way through with the method from post one: clarify, estimate, contract, then high-level to deep-dive to bottleneck, naming the trade-off at every step and drawing on all seven earlier posts.

The capstone: one worked design end to end — requirements, estimation, API and data model, high-level architecture, and deep dives applying the whole series (scaling, caching, sharding, consistency, async, reliability) with explicit trade-offs.

This series is part of a larger body of work by Pratik Dhanave, an Agentic AI Architect writing about production AI systems, distributed systems, and cloud-native engineering. Explore all course series, browse every post, or find topics via the tag index.