Case studies
Case study: ride-sharing
Uber-style dispatch: streaming driver locations into a geo index, matching under contention, trip state and geographic sharding. Start here for the ride-sharing map.
A ride-sharing dispatch system matches a rider who wants a trip with a nearby driver who can take it. The hard parts are not the fare screen. They are three things: ingesting location updates at very high write rates, finding "who is nearest?" quickly, and handing each trip to exactly one driver when many riders compete for the same drivers.
This case study builds the core first: the location pipeline and exclusive assignment. Pricing, ETAs and pooling are add-ons to a correct match.
Requirements
Functional. Riders request a trip with a pickup, a drop-off and a product type. Drivers stream their location while online. The system matches a driver within seconds, shows an ETA, and supports cancellation and reassignment. A trip moves through its states until it is paid.
Non-functional. Locations must be fresh within a few seconds. Matching should finish in seconds at the product level. Two riders must never get the same driver for overlapping trips. City hot spots, such as airports and stadiums, must not overload any one shard.
Estimates
Drivers online in a large region: about 1,000,000
Location update interval: every 4 seconds
Location writes: 1,000,000 ÷ 4 = 250,000 updates per second
Ride requests: thousands per second at most, far fewer than location writesLocation ingestion dominates the write rate. A store that updates one database row per ping, every 4 seconds, for a million drivers will not keep up. The matching path needs the latest position in memory. Historical GPS data can go to a stream and then to cold storage.
How it fits together
Here is the timeline of one trip, with the ideas from each concept page:
t=0.0 s Rider POST /trips (idempotent) → trip is searching
t=0.1 s Matcher reads the cells around the pickup, gets 15 drivers
t=0.3 s ETA ranks the drivers; a compare-and-set claim on driver D succeeds
t=0.4 s Offer pushed to D; trip is offered
t=8.0 s D accepts → trip is accepted; rider is updated; D leaves the available set
t=… D arrives → in progress → completed → payment (idempotent charge)If D never answers, the claim expires after about 15 seconds. The matcher then offers the trip to driver E, and so on, until a maximum radius or timeout returns "no drivers".
The concepts that build this are:
| Step | Concept | What it answers |
|---|---|---|
| 1 | Geospatial indexes | How do you find drivers near a point quickly? |
| 2 | Driver location ingestion | How do 250,000 updates per second reach the index? |
| 3 | Exclusive driver assignment | How does one driver go to one rider? |
| 4 | Trip state machine | How is a trip's state kept correct, from request to payment? |
| 5 | Geo sharding and hot spots | How do you partition by city and handle an airport surge? |
Failure modes
| Failure | Mitigation |
|---|---|
| Location lag | Show a stale warning, widen the search, and skip drivers with old timestamps |
| Matcher crashes mid-offer | Lease timeouts free the driver automatically |
| Index memory is lost | Rebuild from the last stream offsets and driver reconnect snapshots |
| City hot spot | Dedicated capacity, honest waits, and surge pricing |
| Routing service is down | Fall back to straight-line distance with padding, and keep matching |
Surge pricing
Surge pricing is a control loop on aggregates, not on the rider's critical path. Each cell records requests per minute, available drivers and average wait. A multiplier is computed from the demand-to-supply ratio, with caps and hysteresis so prices do not thrash. The trip request reads the current multiplier for its pickup cell. Drivers' heat maps come from the same aggregates.
Later extensions
Carpool pooling is a richer optimization problem on the same location index. Safety features, such as trip sharing and emergency buttons, consume the same trip ID and location stream, so they should not block matching. Observability should trace one trip ID across the matcher, the driver's acknowledgement and the payment.
Common mistakes
- Storing every location ping in a row-based database. The write rate outruns the store.
- Matching with stale positions. Check the timestamp before you offer a trip.
- Ignoring the claim. Without it, two riders can book the same driver.
Key takeaways
- Location writes dominate, so keep an in-memory geo index fed by a stream.
- Use cell-based searches, such as H3 rings, to find nearby drivers.
- Exclusive assignment needs an atomic claim with an expiry, not a hope.
- Model trips as an explicit state machine, stored separately from the location index.
- Partition by geography, and plan for airports and stadiums.
Further learning
Uber's H3 documentation is the reference for the hexagonal index this design uses:
H3: Uber's hexagonal hierarchical spatial indexH3h3geo.org ByteByteGo blog (Alex Xu)Explain complex systems with simple terms, from the authors of the best-selling system design book series. Join over 1,000,000 friendly readers. Click to read ByteByteGo Newsletter, a Substack publication.blog.bytebytego.com
A walkthrough of real-time routing and dispatch, including hexagonal indexing and the location write flood:
Start with geospatial indexes to see how a location becomes a lookup.
Related
Geospatial indexes
How geohashes, quadtrees and H3 hexagons turn "who is near this point?" into a small set of cell lookups, and the boundary trap that catches naive geohash searches.
Driver location ingestion
How a stream of driver location updates, about 250,000 per second for a large region, reaches an in-memory geo index, and why the matchable set holds only available drivers.
Exclusive driver assignment
How two riders competing for the same driver are settled with an atomic claim that expires, and how offers and retries avoid double bookings.
Sharding and partitioning
Split data across machines by choosing a shard key, hashing or ranging it, routing requests, handling hot spots, resharding without downtime and generating IDs that stay unique.
Real-time delivery
How a server pushes updates to clients that did not ask, from polling to WebSockets, and the gateway, pub/sub and reconnect design that serves millions of open connections. Start here for the real-time map.
Case study: ticket booking
Ticketmaster-style inventory under extreme contention, with holds that expire, a virtual waiting room and atomic seat commits so one seat is never sold twice.