</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 7: The Index You Already Have - Deep Dive: Push or Pull — The Fan-Out Decision

Executive Summary: This is the module's central trade-off. Section 6 claimed Maya's update reaches exactly four channels; now you defend that number against the design every candidate reaches for first. We cost out the geospatial index honestly — including the uncomfortable admission that it can express arrival, just expensively — and show it is the right answer to a different question. Then we build the push path on Section 3's fan-out chain, price its read side against the index's, and close on the high-degree tail, a three-way hybrid verdict, and two pushbacks.

The interviewer taps the publish step on the whiteboard. "You said four channels. The obvious alternative is to index everybody's location and run a radius query. Defend your number."

Do not rush this. The way to lose the next ten minutes is to dismiss the index as naive — the interviewer has almost certainly built one, and a candidate who strawmans a reasonable design reveals they never understood it. The way to win is to cost it out fully, then show its costs are matched to a question the product is not asking.

The Pull Design, Taken Seriously

Mechanism. Index all ten million active sharers geospatially; each update rewrites that user's position as a geohash string, a quadtree leaf, an S2 cell. On app open, the service computes the cells covering Maya's query box, reads them, applies an exact haversine filter to trim the corners, and intersects the survivors with her 420 friend IDs.

Get the geometry right here, because this is where candidates wave their hands and a Principal stops them. A precision-5 geohash cell is about 4.9 km on a side at the equator. The 3×3 neighbourhood around it spans 14.7 km edge to edge, which sounds like plenty — but Maya is not standing at the centre of her cell, she is somewhere arbitrary inside it, and all that neighbourhood guarantees from an arbitrary query point is one cell width of margin: about 4.9 km at the equator, and only about 3.9 km of width at San Francisco's latitude, because geohash cell width scales with the cosine of latitude while height does not. Both numbers are less than the 5 km radius. So the covering set is computed from the query's bounding box — expand the point by 5 km, find the cells that intersect that box, read as many as it takes, which is sometimes four and sometimes six — and never fixed at 3×3 on the assumption that nine cells is always enough.

This is how ride-hailing finds drivers and how Yelp finds restaurants, and its advantage is worth conceding out loud: the write path is cheap. One index mutation per update, 333 thousand a second, nothing fanning out at all.

Number. Read time is where it collapses. The cells covering a 5 km box over downtown San Francisco on a Saturday afternoon hold thousands of active sharers; the ones that matter are the handful of Maya's roughly 38 online friends anywhere near her — about four, two of them inside the radius itself. Thousands of rows read to keep four, and the useful fraction gets worse as the product succeeds, because density grows while friendship stays sparse.

Trade-off. Three costs:

  • Read amplification that scales with city density rather than with the friend graph — every concurrent sharer paying for everyone else's presence in their cells. This is the real cost, and the honest version of it is a comparison, not a slogan: see the arithmetic below.
  • Arrival is expressible, but only at write time. Be careful not to overclaim here, because the overclaim is the one an interviewer will punish. "Tell me when a friend shows up nearby" can be served by an index — query it as each point lands, intersect the result with the publisher's friend list, and run the same per-pair state machine. That is precisely what Section 12's geofences do. What it cannot do is serve arrival cheaply: you have replaced a bounded multi-get on the hottest path in the system with a density-scaled range scan, which is the read-amplification cost again, now paid 333 thousand times a second instead of once per app open. The index does not lack the mechanism; it prices it badly.
  • A privacy regression by construction. To answer Maya's question, pull reads thousands of strangers with no relationship to her — and the write-time variant above reads them on every single update. Section 10 argues that privacy here is architecture, not settings; this is the first proof. Push never touches a row outside Maya's graph.

Key Insight: The index is the correct answer to "who is near this point?" — a question about geography, asked by a stranger, with an unbounded answer set. Our product asks "which of my friends is near me?" — a question about a 420-element list that happens to carry coordinates. The friend list is the index: already bounded, already authorised, and keyed by the one attribute that never moves while the user does. The index is not wrong and it is not incapable — it is mis-applied, and Section 12 is where it earns its seat.

Quick check before moving on:

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.