Hands-on System Design with Java Spring Boot

Hands-on System Design with Java Spring Boot

Building Discord : From Socket to Scale

Day 74: Region Selection - Geography Gets You Close, Measurement Gets You Right

Ashburn, Virginia sits about 500km from New York and roughly 6,000km from London. Nobody argues with that. What geography can’t tell you is that a specific transatlantic route had a fiber cut three we

Sep 29, 2026
∙ Paid

The Spring Boot Trap

The naive version of this feature is a lookup table. Resolve the user’s IP to a country or city with a GeoIP database, match it against a static map of region -> nearest voice datacenter, done. It’s fast, it’s simple, and it’s exactly the kind of thing that looks finished in a demo with three users in the same city as the engineer who built it.

It falls apart the moment real geography and real network topology disagree, which is often. Singapore and Jakarta are close on a map and can still have meaningfully different paths to a given Asia-Pacific datacenter depending on which submarine cables and IXPs are involved that week. A user on a mobile carrier’s NAT gateway might get geolocated to a city three states from where they’re actually sitting. And a static table can’t express “this region is fine most of the time but is overloaded right now” — it’s a lookup, not a measurement, so it has nothing to say about the present moment.

I’ve seen this exact failure as a support ticket pattern: a cluster of users in one metro area reporting choppy voice at the same time every day, while every other region looks healthy. The lookup table sent all of them to the same “closest” datacenter, fine at 2am and saturated at 6pm local time. Nothing in a static table can see that. Something that actually measures the path, right before it matters, can.

The Failure Mode

The obvious fix — “just ping every candidate region before picking one” — creates its own problem done the naive way: sequentially. Eight candidates, 200ms timeout each, probed one after another, is a worst case of 1.6 seconds added to every voice channel join before the user hears anything. Nobody waits that long to talk to their friends, and the fix isn’t a shorter timeout — too aggressive a timeout just misclassifies real, healthy regions as unreachable because their honest RTT was 210ms on a slow moment.

A second, quieter failure mode only shows up at scale: running this probe sweep on every join with no caching, for a server with hundreds of people connecting to voice within the same few seconds during a big event. Every one of those joins measures the same thing — clients from the same network, asking the same question, getting the same answer — and a naive implementation runs the full multi-region sweep hundreds of times over for an answer that was going to be identical every time. Wasted probe traffic hitting every candidate datacenter, and added latency for every joiner, entirely self-inflicted.

The Flux Architecture

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 javap · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture