Skip to main content
Uber
Flagship

Uber Dispatch — matching riders to drivers at planetary scale

H3 hexagonal geo-index, DISCO batch matching, and surge pricing — a real-time marketplace serving 10K+ cities and ~28M trips/day.

~1M+ drivers online at peak · ~28M trips/day · <2s match latency

1 · The problem at planetary scale

Uber runs a real-time marketplace: on one side, millions of active drivers with GPS trackers pinging every few seconds; on the other, millions of riders opening the app expecting a car in under 90 seconds. Every request is a geo-constrained optimization problem — which of the drivers within N miles do I match to this rider, and what price do I quote — with strict latency budgets and an economic feedback loop (surge pricing) built on top.

The engineering shape is different from Netflix or Instagram. This is a real-time OLTP + streaming workload where the hot path involves geospatial queries, ML inference, and a marketplace algorithm — not just serving bytes.

2 · Back-of-the-envelope

Cities served
10K+
Countries
70+
Drivers online (peak)
~1M+
Trips/day (peak)
~28M
Driver ping cadence
~4 seconds
Ping RPS (peak)
~250K+
Dispatch decisions/sec
~2-3K
Match latency budget
< 2 seconds

The dominant load is driver location writes, not user requests. 1M drivers × ~4 sec ping cadence ≈ 250K writes/sec — write-heavy, geospatial, and needs to be readable within a second for the next dispatch decision.

3 · Architecture

Uber's dispatch stack has three critical layers: the geo-index that answers "which drivers are near this rider?", the dispatch service (DISCO) that optimizes the match, and the event backbone that keeps pricing, ETA models, and analytics current.

React Flow mini map

4 · H3 — the hexagonal geo-index

Uber built H3, a hierarchical hexagonal grid system, because square grids (like geohashes) have a subtle problem: the distance from a square's center to an edge is not the same as to a corner, so neighbor queries are uneven. Hexagons have equal distance to all six neighbors — which makes "drivers within 1 mile of this rider" a fast, symmetric query.

H3 has 16 resolution levels. At resolution 9, a hex covers roughly 0.1 sq km — big enough to hold ~10 drivers, small enough to answer "drivers near me" in a single hex lookup. When you need a wider search radius, you fetch the target hex + its rings of neighbors — a fast, deterministic operation.

5 · DISCO — the dispatch optimizer

The naive matching approach (match each rider to the closest driver, greedily) is provably worse than the global optimum. If three drivers are near two riders, sending the closest to the first rider strands the second rider with a far driver. DISCO — Dispatch Optimization — batches matches over a short time window (~1-2 seconds) and solves them as a bipartite matching problem, minimizing total pickup time across the batch.

The trade-off is deliberate: individual riders wait up to 2 more seconds for the batch to complete, but the whole system finds a better assignment for everyone. This is the same math behind operations research classics like the Hungarian algorithm, applied at continuously-arriving-stream scale.

6 · Surge pricing

When demand exceeds supply in a hex (or a cluster of hexes), prices multiply. This does two things simultaneously: it prices some demand out (fewer riders click confirm at 2.5×) and it pulls supply in (drivers migrate toward high-multiplier areas). The surge signal is computed per-hex per-minute from the ratio of requests to available drivers.

The economic signal is fed from Kafka streams into a real-time pricing service. Drivers see it visualized on their map so they can choose where to position themselves. This is one of Uber's most-studied and most-controversial mechanisms.

7 · Failure modes at this scale

City-level dispatch outage

Trip DB is sharded by city. When a shard fails, that city stops dispatching — drivers and riders in one city are affected, the rest of the world is fine. This is the whole point of sharding by city.

Redis (driver state) down

Fallback to Cassandra with higher-latency reads. Match times degrade from <2s to <10s. Riders see a longer "finding driver…" screen but the system doesn't stall.

Kafka lag on ETA pipeline

ETA predictions get stale (last-hour data). Dispatch keeps working with degraded ETA accuracy. Alert fires; consumer capacity is scaled up. Users see slightly-off ETAs for the duration.

Location ping storm

Popular event ends, 100K drivers turn on simultaneously. Edge absorbs the spike via WebSocket connection reuse; writes are batched at the geo-index tier. This is a designed-for scenario, not a black-swan.

8 · Interview soundbite

"Uber's dispatch stack is a real-time marketplace with three critical layers. First: H3 hexagonal geo-index, chosen over geohashing because hexagons have uniform neighbor distance — this makes 'drivers near me' a single-hex lookup. Second: DISCO, which batches matches over ~1-2s windows and solves them as bipartite matching rather than greedy nearest-driver, trading 2s of latency for a globally better assignment. Third: Kafka streams driving surge pricing and ETA models continuously — a real economic feedback loop on the marketplace. Sharding is by city so a shard failure is a city-level outage, not global."

9 · Sources