// HACKER NEWS — CYBERSECURITY
Why didn't anybody tell me about Redis hash slots?
I work on a service that decides which courier gets offered your delivery at a gig economy delivery app. When you open the app and ask for something to be brought to you, some code somewhere has to decide which of the couriers should be offered the job. We’re the ones who make those offers.
I’m not at liberty to discuss the myriad parameters that go into the decision, but a pretty obvious one you can suss out externally without knowing much is distance. To make good matches, we need to know how far away is everybody, really. Straight-line distance will tell you it takes ten minutes to get across a river with no bridge. For that we lean on a routing engine, which is far and away the biggest contributor to our own latency. We have very specific latency targets that need to be respected. We’re basically always trying to empty a bucket in a set amount of time, and when the bucket overflows, everybody gets wet.
As a heads up, I’m not at liberty to discuss specific figures or terms we use at work. I can say that a service sped up tremendously, I can’t say it went from 600ms to 100ms, for example.
A busy area needs a tremendous amount of route estimates to get through a single pass at assigning work, and it needs them again continuously, for as long as the business is running. Handling this scale is a constant concern.
The useful thing about those estimates is that they’re frequently repetitive. It doesn’t take the guy three houses down from me any meaningful amount more or less time to get to the grocery store than it takes me, and neither of us could tell the difference between driving to that grocery store and driving to the gas station in its parking lot. Restaurants, meanwhile, do not move at all. Two couriers a block apart produce two nearly identical route requests, and thirty seconds later, from two new positions, they produce two more.
Without any caching layer between us and the routing engine, you’re invariably duplicating work, re-calculating what are functionally the same distances on a regular cadence for minutes at a time.
A process-local cache also doesn’t work here. The process that computes an estimate is rarely the one that needs it next, so the cache has to be shared.
Caching on raw coordinates is a non-starter. You need to use H3 to dedupe the coordinates. H3 breaks the world up into differently-sized hexagons, and allows you to fetch the hex’s ID from a given coordinate pair.
The resolution is a lever. Too wide a hex size leads to higher hit rates, and less accurate estimates. Too small a hex effectively swaps one coordinate identifier for another.
So the key was ::, the value was the estimate, and the write path was an MSET. Easy peasy, right?