70k/s
swipes a second on a Sunday evening
Assume 50M daily users swiping about 40 cards each. That’s 2 billion swipes a day, 23k a second on average, three times that at peak.
Where does the search run?
Bad: One global index
A query from Pune searches documents from Peru, on every replica.
Good: Geoshards, balanced by load
Ask only the two or three geoshards your circle covers.
Shards hold equal load, not equal area
Walk S2 cells along a Hilbert curve and pour in each cell’s load. When the next cell would overflow, seal the geoshard.
Search, filter, check the seen-set and rank on every fetch? That’s 400–600 ms at p99.
The trick
Build decks ahead, 200 ranked IDs per user in Redis. Each fetch pops 25, well under 50 ms.
12 KB
per user to remember 10,000 swipes
An exact set needs 320 KB each, 16 TB for 50M users. A Bloom filter at 1% needs 600 GB, and it never repeats a face.
Both swipe right in the same 50 ms
Two rows, check then write, and both see “no”, so the match is lost. One row per pair, and only the second upsert sees both flags.
Tell Rohan within 2 seconds
- Presence maps Rohan to his gateway node
- Send the match down his WebSocket
- No socket, or no ack in 3 s? Push
- Dedupe by match ID; sync on reconnect
Remember
Shard search by load, not area. Build decks ahead, skip seen faces with a Bloom filter, match on one atomic row per pair, and notify over sockets.