Skip to content

Series

System Design for Working Devs

Complete · 12 parts in engineering

A field guide to system design for the engineer who has to make the call and ship it — no FAANG-scale hand-waving. The five axes of every tradeoff, the CAP theorem without the folklore, idempotency, caching, designing for failure, and a full worked design at the end.

Introduction

  1. 0 How to Think About System Design System design has no right answers — only tradeoffs along a few axes: latency, consistency, availability, cost, and complexity. The intro to a working dev's field guide, and how to read the rest of it.

The Physics

  1. 1 Latency, Throughput, and Napkin Math The numbers every engineer should know by feel — memory vs SSD vs network — plus why p99 matters more than the average, and how a five-minute capacity estimate saves you from building for a scale you don't have.
  2. 2 Scaling and Statelessness Scaling up buys a bigger box; scaling out adds more boxes. But scaling out only works if your app is stateless — and the sticky session is the hidden state that quietly breaks it. Where state actually belongs.

Consistency & Data

  1. 3 The CAP Theorem (and PACELC) When the network splits, you get consistency or availability — not both. The CAP theorem stated without the folklore, why 'CA' isn't a real option, and PACELC: the tradeoff that bites even when nothing is broken.
  2. 4 Consistency Models 'Eventually consistent' isn't one thing — it's a whole menu between strong and eventual, and the middle options are where real apps live. Read-your-writes, monotonic reads, and the bugs that appear when you pick wrong.
  3. 5 Replication and Quorums Copying data across machines buys read capacity and survives a dead server — and creates every consistency headache in the series. Leader/follower, sync vs async, failover's split-brain risk, and quorums as the dial between them.

Between Services

  1. 6 Sync vs Async Synchronous means the caller waits; asynchronous means the work is handed off to a queue and the caller moves on. When to decouple with a queue, what it buys (resilience, smoothing, speed), and the new problems it hands you.
  2. 7 Idempotency and Safe Retries The network makes every call at-least-once, never exactly-once — so the same request will sometimes arrive twice. Idempotency is what makes a repeat harmless: idempotency keys, dedup, and why 'exactly-once' is a lie you engineer around.

Speed & Failure

  1. 8 Caching Patterns and Their Failure Modes Cache-aside, write-through, write-behind — the strategies, and the failure modes that turn a cache into an outage: the stampede when a hot key expires, and why every cache is a bet that stale data is acceptable.
  2. 9 Designing for Failure Everything fails: servers, networks, dependencies. The question is never whether, but how gracefully. Timeouts, retries with backoff and jitter, circuit breakers, bulkheads, and graceful degradation — the toolkit for staying up when parts don't.

The User's Clock

  1. 10 Optimistic UI and Prefetching The fastest system is the one that feels instant, and feeling instant is a design problem, not just a speed problem. Optimistic UI, prefetching what the user will probably need next, and optimistic locking so assuming success stays safe.

Capstone

  1. 11 A Worked Design, End to End The whole toolkit on one real system: an appointment booking and reminder service. Napkin math first, then the CAP call per feature, idempotent bookings, async reminders, cached availability, and where every previous chapter lands.