Skip to the chapter
←System DesignGGroundworkSDSystem Design
System Design/Advanced/A12
32 / 36 written chapters
/

The cover
  1. B1The mental model
  2. B2Client-server basics
  3. B3Vertical vs horizontal
  4. B4Databases in design
  5. B5Caching fundamentals
  6. B6APIs & communication
  7. B7Walkthrough: URL shortener
  1. I1Load balancing in depth
  2. I2CDNs
  3. I3Message queues & async
  4. I4Consistency models
  5. I5Replication
  6. I6Rate limiting & throttling
  7. I7Designing for availability
  8. I8Storage systems
  9. I9Search systems
  10. I10Microservices
  11. I11Security basics
  12. I12Walkthrough: feed/chat
  13. I13Walkthrough: notifications
  1. A1CAP theorem in depth
  2. A2Transactions and isolation
  3. A3Storage engines
  4. A4Sharding at scale
  5. A5Time, ordering and IDs
  6. A6Distributed consensus
  7. A7Batch & stream processing
  8. A8Fault tolerance
  9. A9Observability at scale
  10. A10Release safety
  11. A11Capacity estimation
  12. A12Case studies
  13. A13Walkthrough: key-value store
  14. A14Walkthrough: web crawler
  15. A15Walkthrough: payments
  16. A16Tradeoff thinking

SDA12 · Part 3 · Advanced

Real-world case studies

Six systems you use every week, one or two interesting decisions each, the bill that came with them, and what has changed since.

23 min read2 diagrams9 sections0 exercises
32 of 36

In this chapter

  • How to read these — and how not to use them
  • Twitter timelines — the hybrid fan-out
  • Netflix — precomputed placement, and failure as a habit
  • Uber — a spatial index is a sharding decision
  • WhatsApp — constraining the product is a scaling lever

and 4 more

about 23 min
09On this page
  1. How to read these — and how not to use them
  2. Twitter timelines — the hybrid fan-out
  3. Netflix — precomputed placement, and failure as a habit
  4. Uber — a spatial index is a sharding decision
  5. WhatsApp — constraining the product is a scaling lever
  6. Instagram — boring database, aggressively applied
  7. Discord — coalescing in front of a hot partition
  8. The six systems, seven decisions, on one line each
  9. Using a case study without sounding like you read a blog post

How to read these — and how not to use them

Everything below is drawn from publicly discussed architecture: conference talks, engineering blog posts, papers. Each is a snapshot of a system at a point in time, usually years ago, and in several cases the company has since rebuilt the thing described. None of it is current internal truth, and you should say so if you cite it. Each section below names its source year and carries a "what has changed since" line, so you can see how stale the snapshot is. Where a claim could not be traced to a dated primary source, the text says "reported" or "secondary write-up" instead of stating it as fact. The value is not the architecture; it is the reasoning, and specifically the part that most retellings skip: what the clever decision cost.

Used badly, case studies are name-dropping — "I'd do it like Twitter" signals that you have read a blog post, not that you can design. Used well, they are a compressed argument: "there is a known pattern for the celebrity problem; it is a hybrid, and the threshold is a tunable I'd choose from the follower histogram and a cost model." Each section below ends with the one transferable move.

Twitter timelines — the hybrid fan-out

The problem, as Twitter engineers described it in QCon talks in 2012 and 2013 (the numbers here come from a 2013 summary of the "Timelines at Scale" talk): home timeline reads ran at about 300,000 requests per second against tweet writes of roughly 6,000 per second. A read-time query — "fetch every tweet from everyone this user follows, merge, sort" — is a scatter across thousands of partitions on the hottest path in the product. The fix was to invert it: on write, push the tweet id into a precomputed per-follower timeline list held in memory (Redis), capped at 800 entries. The read then becomes a single list fetch. Reads went from a distributed join to an O(1) lookup.

The cost is write amplification, and it is brutal at the tail of the follower distribution. The same summary cites an account with about 31 million followers, where one tweet means about 31 million list insertions and, in the worst case, up to five minutes to reach everyone. Across the network, total fan-out ran to about 30 billion timeline deliveries a day. The summary also reports where Twitter was heading: exploring a hybrid, fanning out on write for ordinary accounts and, for the small set of very-high-follower accounts, skipping fan-out and merging their recent tweets in at read time. Note the tense: in 2013 that hybrid was being explored, not finished, so "Twitter uses a hybrid" is an inference from a snapshot, not a settled fact.

tweet by ordinary account fan-out workers timeline cache · follower A timeline cache · follower B timeline cache · follower C tweet by celebrity 30 M followers celebrity tweet store write once, no fan-out read path: merge cached list + celebrity pull write cost is paid by the 99.9% of accounts where it is cheap; read cost is paid only for the handful of accounts where fan-out would explode
The threshold is the design. Too low and you pay the merge cost on every read; too high and one celebrity tweet stalls the fan-out queue for everyone behind it.

What to steal in an interview: whenever a workload has a power-law distribution, propose treating the head and the tail differently, and name the threshold as a tunable. "Fan-out on write below some follower count, fan-out on read above it, and I'd make that a config value because the right number depends on the follower histogram and a cost model" is a complete answer to a whole family of feed, notification and subscription questions. There is no industry-standard number: reasonable thresholds sit anywhere from roughly 100,000 to 1,000,000 followers.

What has changed since (source years 2012-2013): the design above is a 2013 snapshot. X's open-sourced "For You" repository (updated in 2026) describes a different pipeline: in-network candidates come from an in-memory store of recent posts by accounts you follow, out-of-network candidates come from machine-learned retrieval, and a transformer model ranks them. The precomputed Redis list of 800 ids is no longer how that feed is described.

Netflix — precomputed placement, and failure as a habit

Netflix's Open Connect programme, publicly described from around 2012, inverts the usual CDN model. Instead of caching reactively on a miss, Netflix offers physical appliances that sit inside ISP networks, and fills them during off-peak windows with content chosen by per-region popularity (Netflix's own overview says it can predict with high accuracy what members will watch and when). Video is unusually well suited to this: the catalogue is finite, changes slowly, and next-Tuesday's demand is genuinely predictable from this-Tuesday's. So the cache miss — the expensive event that dominates ordinary CDN design — is mostly engineered out of existence rather than optimised.

The cost is that you are now running a hardware logistics operation: manufacturing, shipping (Netflix's current ISP page quotes about a week), ISP agreements, and operating boxes you cannot physically reach. That is a real organisational commitment, and it only pencils out because streaming video is a large enough fraction of internet traffic to justify it. Do not propose it for a service serving 200 KB images.

The second Netflix idea is cultural rather than architectural: Chaos Monkey, introduced in Netflix's 2011 Simian Army write-up, which randomly terminates production instances on purpose. The reasoning is that redundancy you have never exercised is a claim, not a property — failover paths rot, runbooks go stale, and the first real test of your multi-AZ story should not be at 3am. The cost is that you must build the resilience first; switching on failure injection in a system that isn't ready is just an outage you scheduled.

What has changed since (source years 2011-2012): Netflix's current Open Connect pages still describe appliances embedded in ISP networks with nightly fills, so the idea has held up. The wider Simian Army project, by contrast, is retired and unmaintained; Chaos Monkey itself lives on as a standalone service that is configured through Spinnaker.

What to steal: two sentences. "If demand is predictable, precompute placement instead of caching reactively." And, at the end of any availability discussion, "I'd verify the failover path with scheduled failure injection, because an untested failover is a broken failover." The second one costs you fifteen seconds and reliably lands.

Uber — a spatial index is a sharding decision

Matching riders to drivers is a continuous geospatial query: given a point, find nearby available supply, fast, while every driver's position updates every few seconds. Uber's publicly described answer (the H3 library, announced on Uber's engineering blog in June 2018) indexes the world as a hierarchy of hexagonal cells, each addressed by a 64-bit id, at sixteen resolutions from continent-sized down to cells of under a square metre. A proximity query becomes "look up this cell and its ring of neighbours" — a key lookup, not a geometric search.

Hexagons rather than squares for a specific reason: a hexagon has six neighbours and all six centroids are equidistant. A square grid has four edge-neighbours at distance d and four corner-neighbours at d√2, so "expand the search by one ring" means different things in different directions, and any smoothing or gradient over the grid is distorted. The cost is that hexagons do not tile hierarchically: you cannot subdivide a hexagon into smaller hexagons exactly, so containment across resolutions is approximate (H3's documentation says geographic containment is approximate while the logical parent-child relation in the index is exact), and wrapping a sphere in hexagons mathematically requires exactly twelve pentagons (H3 orients its icosahedron so all twelve fall in the ocean). That is a genuine correctness footnote you inherit.

The deeper point is how a spatial index relates to sharding. Uber's H3 post describes using the grid for pricing, dispatch and analysis; it does not say H3 cells are database shard keys. The sharding claim comes from a separate, older source: secondary summaries of Uber's 2015 QCon talk on its dispatch platform report that it used S2 cell ids (a different spatial index) as the sharding key. Treat that as a 2015 secondary-source description of a system that has since been replaced. Sharding by geography is the natural choice, and it imports the natural failure: geography is not a uniform load distribution. A stadium at kickoff is a hot cell, and no amount of consistent hashing helps because the load genuinely is in one place. The mitigations are the usual ones from the sharding chapter — split hot cells to a finer resolution dynamically, and keep the dispatch tier able to rebalance ownership between nodes.

What to steal: for any "find things near me" prompt, name a concrete index (H3, S2, geohash, or a PostGIS R-tree) and immediately name the resolution tradeoff — coarse cells mean fewer lookups but more candidates to filter; fine cells mean more lookups but tighter results. Then volunteer the hot-cell problem before the interviewer does.

What has changed since (source years 2015 and 2018): H3 is still maintained as open source with public documentation. The dispatch architecture from the 2015 talk is more than a decade old; use it as a pattern for geographic sharding, not as a description of Uber today.

WhatsApp — constraining the product is a scaling lever

The figures with a traceable source: in February 2014, when Facebook bought it, Sequoia's note counted more than 450 million active users and 32 engineers (a ratio of about 14 million users per engineer). WhatsApp's own 2012 blog post described holding more than two million concurrent TCP connections on a single machine (2.28 million sockets on a 24-logical-CPU server with about 96 GB of RAM), running Erlang on FreeBSD. Erlang's runtime is the reason it is even plausible — millions of cheap preemptively-scheduled processes, per-process heaps so garbage collection is per-connection and measured in microseconds rather than a stop-the-world pause, and supervision trees that restart a crashed connection process without touching its neighbours. Add heavy kernel tuning of socket buffers and file descriptor limits. The post does not state a per-connection memory figure; dividing the 35 GB of active memory in its output by 2.28 million sockets gives roughly 15 KB each, which is our rough estimate from active memory alone, not a figure from the post. (The Erlang runtime properties above are general features of that platform, not claims from the post.)

But the runtime is only half of it. The other half is that WhatsApp refused features. The server did not keep message history: WhatsApp's privacy policy still says messages are stored on your device and deleted from its servers once delivered, and that an undelivered message is held in encrypted form for up to 30 days. That single product decision is worth revisiting with the arithmetic from the capacity chapter: retaining history costs petabytes a year; retaining only undelivered messages costs tens of gigabytes. Minimal server-side state and a narrow feature surface are a plausible reason the team could stay small, though the sources listed at the end of this chapter give the headcount, not the cause.

The cost is severe specialisation. Hiring Erlang engineers is hard, the ecosystem is small, and the architecture is unusually inflexible in the direction of adding features — which is precisely what a company adds after an acquisition.

What has changed since (source years 2012 and 2014): the product surface has grown. In June 2025 Meta announced channel subscriptions, promoted channels and ads in the Updates tab (which hosts Status and Channels), while saying personal chats stay end-to-end encrypted and are not used for ads. A WhatsApp with no advertising surface and no feed-like tab is therefore a pre-2025 picture, and the 2012-2014 numbers describe a much smaller product than Meta runs now.

What to steal: when the requirements phase is happening, ask whether a feature is actually required, and put a number on what it costs if it is. "Do we need server-side history? If yes I need a petabyte-scale message store; if no, a 40 GB queue covers it" is the highest-leverage question in the whole interview, and almost nobody asks it. Also: name your per-connection memory budget on any real-time design.

Instagram — boring database, aggressively applied

Instagram is the standing counterexample to "web scale needs a new database." Through its hypergrowth years its core data lived in PostgreSQL, sharded by user id, with two decisions that made it work. (It was not Postgres alone: see the "what has changed since" note below.)

First, blobs left the database immediately — photos went to object storage behind a CDN, and Postgres held only metadata rows. Re-run the capacity arithmetic and it is obvious why: the blob path is measured in petabytes and the metadata path in terabytes. Keeping them in the same system means sizing your relational store for the wrong workload.

Second, logical shards. Rather than mapping users onto physical machines, they mapped users onto a few thousand logical shards (Postgres schemas), then mapped many logical shards onto each physical machine. Growing the cluster means moving logical shards between machines — no re-hashing, no application change. Their id generation scheme, described in a 2012 post, packs the shard into the primary key itself (the post's own example uses 2,000 logical shards and a shard computed as user id modulo the shard count; 13 bits allows up to 8,192):

64-bit id =  41 bits  millisecond timestamp   // 2^41 ms is ~69.7 years from a custom epoch (the 2012 post says "41 years")
           + 13 bits  logical shard id        // 8,192 logical shards
           + 10 bits  per-shard sequence      // per-table auto-increment mod 1,024: unique only while a shard mints at most 1,024 ids per ms

  ids are roughly time-sortable  -> good index locality on an append-heavy table
  the shard is IN the id         -> route a request without a lookup table
  generated in the database      -> no separate id service to keep available

The cost is everything you give up by sharding a relational database: no cross-shard joins, no cross-shard transactions, no global secondary indexes, and application code that must always know the shard key. Connection management becomes its own project — thousands of app processes against a Postgres backend that forks a process per connection means a connection pooler such as PgBouncer is usually needed.

What has changed since (source year 2012): Instagram's 2018 engineering post says it began using Cassandra in 2012 to replace Redis for fraud detection, Feed and the Direct inbox, first on AWS and later on Facebook's infrastructure when the rest of Instagram moved. So the full picture is sharded Postgres for core relational data plus Cassandra for append-heavy, large-scale feed-style data, and the infrastructure it runs on is no longer the one the 2012 post describes.

What to steal: "I'd start with Postgres" is a legitimate and often correct answer, and the way to make it credible is to pair it with the scaling path — blobs out to object storage, logical shards from day one so rebalancing is a data move rather than a rewrite, and a shard-encoded id. Say the sentence "sharding costs me joins and cross-shard transactions" before the interviewer asks.

Discord — coalescing in front of a hot partition

Discord's two posts on message storage — billions of messages on a 12-node Cassandra cluster (January 2017), and trillions of messages after a move from 177 Cassandra nodes to 72 ScyllaDB nodes (March 2023, describing a cutover completed in May 2022) — are unusually honest about what went wrong in between, which makes them the most instructive pair on this list.

The original data model is worth memorising as a template: partition key of (channel_id, bucket) where the bucket is a fixed time window, clustered by a snowflake message id in descending order. The bucket exists because a partition keyed on channel alone grows without bound; in the 2017 post a bucket covers about ten days and keeps a partition under roughly 100 MB, which makes "load the most recent messages" a single partition read with no sorting.

What broke was not throughput but tail latency, and the causes are a tour of distributed-storage failure modes. Hot partitions: a handful of enormous channels received a wildly disproportionate share of reads. Tombstones: deletes in an LSM store are writes, and a range scan must read past every tombstone in the range, so a heavily-moderated channel became slow to read. And JVM garbage collection: stop-the-world pauses on Cassandra nodes produced multi-second stalls that showed up purely as p99 spikes — invisible in an average, invisible in the error rate, exactly the pattern the observability chapter warns about.

The 2022 migration (written up in 2023) had two parts. ScyllaDB — a C++ reimplementation of Cassandra with a shard-per-core architecture and no garbage collector — removed the GC pauses. More interesting is what they put in front: intermediate "data services" written in Rust that coalesce concurrent identical requests. When ten thousand clients ask for the same channel page in the same instant, the first request goes to the database and the rest wait on its result; consistent-hash routing sends each channel to the same service instance so the crowd actually meets in one place.

10,000 clients same channel, same instant data service (Rust) coalesce by (channel_id, bucket) ScyllaDB hot partition 10,000 reads/s 1 read this is a cache with a time-to-live of "the duration of one query" — no TTL to tune, no invalidation, and the hot partition never notices the crowd
Request coalescing is the cheapest tool against a read hotspot because it adds almost no staleness — unlike a TTL cache, nothing is served from older than one in-flight read. The one catch: a caller that joins an in-flight read gets a result from a query that started before it arrived, so a client that wrote a moment ago can miss its own write unless writes also break the flight.

What to steal: request coalescing (also called single-flight or request collapsing) is a genuinely reusable move, and mentioning it marks you as someone who has fought a thundering herd. It is also the correct answer to cache-stampede questions from the caching chapter: on a miss, one request refills while the others wait, instead of ten thousand simultaneous refills.

What has changed since (source years 2017 and 2023): the 2017 Cassandra design was replaced in 2022 (177 Cassandra nodes became 72 ScyllaDB nodes, each with about 9 TB of disk). I found no later Discord write-up that supersedes the March 2023 post, so treat it as the latest public snapshot rather than a statement about today.

The six systems, seven decisions, on one line each

SystemThe one interesting decisionWhat it costThe transferable move
Twitter timelines (2012-2013; superseded)Fan-out on write, with a hybrid for high-follower accounts under explorationEnormous write amplification; a threshold that must be tunedSplit head and tail of a power-law workload; name the threshold
Netflix Open Connect (2012; still described today)Predictive overnight cache fill into ISP-hosted appliancesRunning a hardware logistics businessIf demand is predictable, precompute placement rather than caching reactively
Netflix Chaos Monkey (2011; Simian Army retired)Inject failure in production, continuouslyRequires the resilience to exist firstAn untested failover is a broken failover
Uber H3 (2018) and dispatch (2015 talk)Hexagonal hierarchical spatial index; the 2015 dispatch talk (secondary summaries) sharded by S2 cell idApproximate containment across resolutions; twelve pentagons; hot cells at eventsName the spatial index and its resolution tradeoff; volunteer the hotspot
WhatsApp (2012 post, 2014 headcount)Erlang + kernel tuning for millions of sockets per box; no server-side historyExtreme specialisation; a deliberately tiny feature surfaceCutting a requirement is a scaling lever — put a number on it
Instagram (2012 post)Sharded Postgres with logical shards and shard-encoded ids; blobs in object storage (Cassandra added for feed-style data)No cross-shard joins or transactions; connection pooling as a projectBoring database plus an explicit scaling path beats an exotic one
Discord (2017 post → 2023 post)Bucketed partitions; then request coalescing in front of ScyllaDBA trillions-of-messages migration; a bespoke service tier to maintainCoalesce concurrent identical reads; GC pauses surface as p99, not as errors

Using a case study without sounding like you read a blog post

  • Lead with the problem, not the company. "This has the celebrity fan-out shape" is analysis; "Twitter uses Redis" is trivia. Name the company second, as a citation.
  • Date it and hedge it. "As of their 2017 write-up" costs you four words and protects you completely — the interviewer may work there and know it changed.
  • Always state the cost. A candidate who says "and that cost them cross-shard joins" has understood the decision. A candidate who lists only the benefit has memorised it.
  • Never argue from authority. "Netflix does it" is not a reason. "Our demand is predictable in the same way theirs is, which is what makes precomputed placement work here" is a reason.
  • Scale-check the analogy out loud. Most of these solve problems that appear at a much larger scale than a small product has. If the prompt is a 100k-user product, the correct use of the case study is to explain why you are not doing it yet — which sets up the tradeoff-thinking chapter's central point.
  • The pitfall: importing a whole architecture instead of one idea. These companies each had a specific constraint that justified a specific cost. Steal the reasoning; leave the org chart.

Dry run: using the Twitter case study inside a live interview answer

Prompt: "Design a social feed where a handful of accounts have 10M+ followers." Applying the six moves above to that one case study, in order.

MoveWhat you'd actually sayWhy it scores
1. Lead with the problem, not the company"This has the celebrity fan-out shape — a power-law follower distribution, so write amplification blows up for a tiny minority of accounts."Analysis of the problem shape, not a name-drop
2. Date it and hedge it"As Twitter's engineering team described it around 2013 — this may well have changed since."Four words of hedging protects you if the interviewer knows it changed
3. Always state the cost"The fix was fan-out on write, but it cost real write amplification at the tail — a 30M-follower account means 30M list insertions per tweet."Shows you understood the decision, not just the punchline
4. Never argue from authority"Our load isn't Twitter's, but if our follower distribution is similarly power-law, the same split should hold for the same reason — it's write cost that explodes, not read cost."Reasons from the property, not from "Twitter does it"
5. Scale-check the analogy"This only pays off once the account tail is large enough for 30M-insert fan-outs to happen regularly. At a few hundred thousand users I'd skip the hybrid and fan out on write for everyone."Matches the chapter's own point that most of these solve problems at a scale a small product has not reached
6. The pitfall, avoided"I'm borrowing the specific idea — split head and tail, make the threshold a tunable — not the rest of Twitter's stack."Steals the reasoning, leaves the org chart

Every row is doing the same test: does this sentence teach the interviewer something about this design, or does it just prove you read a blog post? A case study only earns its place in the answer when the answer would be weaker without it.

Before you move on
  • Name the "what to steal" one-line takeaway for at least three of the six case studies, without re-telling the whole story.
  • Explain why Twitter's fan-out threshold is a tunable rather than a fixed number, and say what it depends on.
  • For any two case studies, say how old the source is and what has changed since, in one sentence each.
  • For any case study you cite, state what it cost — not only what it solved.
  • Say why you'd hesitate to propose Netflix's Open Connect model for a service serving 200 KB images.
  • Walk a case study through all four framing moves (problem-first, dated and hedged, cost-stated, scale-checked) in one interview answer without lapsing into name-dropping.
Sources and further reading
  • InfoQ: Timelines at Scale (Raffi Krikorian, QCon 2013) — the primary talk on Twitter's timeline architecture; the figures used here come from a summary of it
  • High Scalability: the architecture Twitter uses (2013 summary) — secondary write-up with the 300k read QPS, 6,000 writes, 800-entry lists and the hybrid being explored
  • xai-org/x-algorithm on GitHub (2026) — the current open-sourced For You pipeline: in-memory recent posts, retrieval, transformer ranking
  • Netflix Open Connect overview — off-peak fill windows and predictable demand, in Netflix's own words
  • Netflix Open Connect site — appliances embedded in ISP networks and nightly fills today
  • Netflix Simian Army repository — states the project is retired and no longer maintained
  • Chaos Monkey documentation — what Chaos Monkey does today and its Spinnaker configuration
  • Uber Engineering: H3 (2018) — hexagons, 16 resolutions, 64-bit cell ids, twelve pentagons, and the uses Uber names
  • H3 documentation: indexing — hexagons do not cleanly subdivide, containment is approximate
  • High Scalability: how Uber scales its real-time market platform (2015 summary) — secondary write-up of the 2015 dispatch talk, including S2 cells and consistent hashing
  • WhatsApp: 1 million is so 2011 — 2.28 million connections on one FreeBSD/Erlang server
  • WhatsApp privacy policy — messages stored on devices, deleted from servers after delivery, undelivered ones held up to 30 days
  • Sequoia: four numbers that explain the WhatsApp acquisition (2014) — 32 engineers and over 450 million active users
  • WhatsApp blog: more channels and businesses (June 2025) — ads, promoted channels and subscriptions in the Updates tab
  • Instagram Engineering: sharding and IDs at Instagram (2012) — the 41/13/10-bit id layout and logical shards
  • Instagram Engineering: Cassandra tail latency (2018) — Cassandra replacing Redis from 2012 and the move to Facebook infrastructure
  • Discord: how we store billions of messages (2017) — bucketed partitions, tombstones, GC pauses on 12 Cassandra nodes
  • Discord: how we store trillions of messages (2023) — 177 Cassandra nodes to 72 ScyllaDB nodes, Rust data services and request coalescing

Claims in this chapter were checked against these sources in October 2026. Figures marked "planning figure" are rules of thumb, not guarantees.

✓Practise

5 questions drawn from 8, scored out of 5. This is practice: it runs in your browser, saves nothing and does not change what you have marked read.

A12

Finished reading?

0 of 36 chapters read in this series

→Next stop

  1. A11Previous · A11Capacity estimation
  2. A12you are here
  3. Next · A13Walkthrough: a key-value storeA Dynamo-style store is not one clever idea but eight ordinary ones bolted together, and the interview is about the decision you make at each seam.25 min read

01On this page

9 sections · 0%

  1. 01How to read these — and how not to use them
  2. 02Twitter timelines — the hybrid fan-out
  3. 03Netflix — precomputed placement, and failure as a habit
  4. 04Uber — a spatial index is a sharding decision
  5. 05WhatsApp — constraining the product is a scaling lever
  6. 06Instagram — boring database, aggressively applied
  7. 07Discord — coalescing in front of a hot partition
  8. 08The six systems, seven decisions, on one line each
  9. 09Using a case study without sounding like you read a blog post

[] chapters · t top