Why I Finally Understand What Makes Geospatial Search Actually Hard
Admin User
Author
Last year, I was debugging a delivery tracking feature for a client in Karachi. Users were complaining that the app would occasionally skip nearby riders—sometimes missing someone literally 50 meters away. I was doing what every junior developer does when facing performance issues: I optimized the database query. Added indexes. Tweaked the SELECT statement. Nothing worked. The real problem wasn't in my SQL. It was in my approach to thinking about space itself.
That's when I started reading about how companies like Uber actually solve this problem, and it completely shifted my perspective. This isn't just a database optimization problem. It's a geometric one. And geometry, it turns out, is way more important to product performance than I'd given it credit for.
The "Everyone On Earth" Problem
When you're trying to find the nearest available driver for a rider, you're not running a query on a few hundred records. You're potentially searching through millions of concurrent locations. A naive distance calculation against every single driver? That's asking your database to do millions of floating-point computations in microseconds. It's not happening.
The real insight here is that this problem demands spatial thinking, not just database optimization. You can't brute force your way through millions of comparisons. You need to be smarter about the space you're searching through.
Why Squares Fail (And Why I Didn't Notice)
Most developers who haven't done geospatial work before (guilty) assume that any regular grid will work fine. Geohash, the common approach, divides the world into squares. Sounds reasonable.
But here's the killer problem I learned about: the edge case—literally. Two people standing 50 meters apart on opposite sides of a grid boundary have completely different hash prefixes. Your system doesn't know they're neighbors at all. The workaround? Search the current cell plus all 8 surrounding cells. But this creates massive false positives, especially at corners, which wastes computation checking drivers that are obviously too far away.
It's a band-aid solution. And I hate band-aid solutions in production code.
Hexagons Actually Solve This
Uber built H3 specifically to fix what Geohash gets wrong. Instead of squares, they use hexagons. This isn't just a cosmetic choice.
With hexagons, every neighboring cell is at the same distance from the center. With squares, corner neighbors are √2 times further away than edge neighbors. That unevenness creates real problems when you're trying to find "nearby" anything. Hexagons are equidistant. Your search radius actually means something consistent.
What really impressed me was the multi-resolution approach. H3 has 16 levels of granularity—from continental (level 0) to street-level precision (level 12). Uber uses resolution 8 for driver matching, which gives them cells around 0.74 km². That's specific enough to be useful but broad enough to avoid needless computation.
How It Actually Works in Practice
The algorithm is elegant. Convert a rider's coordinates to an H3 index. Pull all drivers from that hexagon and its immediate neighbors (a K-Ring, 7 cells total). If you don't have enough candidates, expand outward to the next ring. Done.
In Go (which I've been working with more lately), this is straightforward:
func findNearbyDrivers(riderLat, riderLng float64, searchRadius int) []string {
riderCell := h3.LatLngToCell(
h3.LatLng{Lat: riderLat, Lng: riderLng},
8,
)
searchCells := h3.GridDisk(riderCell, searchRadius)
var driverIDs []string
for _, cell := range searchCells {
cellKey := fmt.Sprintf("drivers:h3:%s", cell.String())
ids := redisClient.SMembers(ctx, cellKey).Val()
driverIDs = append(driverIDs, ids...)
}
return driverIDs
}
The key insight: you're not doing distance math at all. You're doing lookups. A Redis SMEMBERS on a spatial index is orders of magnitude faster than computing Haversine distances for millions of points.
My Honest Take
This is system design done right—solving the problem at the geometric level rather than fighting it at the optimization level. But I'm also thinking about where this breaks down. H3 is brilliant for ride-sharing because you only need "nearby" within a few kilometers. What about use cases where precision matters more? Or where the geographic distribution is wildly uneven?
Also, implementing H3 means adding a dependency and operational overhead. For a smaller system where you're tracking hundreds of drivers in a city, you might be overthinking it. Know your scale before you optimize.
What I'm Doing Differently
I'm redesigning that Karachi delivery system around spatial indexing instead of brute-force querying. And I'm thinking much harder about the geometric properties of the problem before I write code.
Have you hit geospatial scaling issues in your own work? How did you solve them?
Source: This post was inspired by "[System Design] H3 Geospatial Indexing: How Uber Finds Nearby Drivers with Hexagonal Spatial Index" by Dev.to. Read the original article