All questions
#16Location & MobilityHard

Design Uber or Lyft

Match riders with nearby drivers and track every trip live.

Uber logo
Lyft logo
Doordash logo
Amazon logo

Asked at Uber, Lyft and 3 more

3 min read·8 sections

Uber and Lyft match a rider with a nearby driver in seconds, then track the trip live until drop-off. The system revolves around location: millions of drivers send their position every few seconds, and the matching service must find the closest available ones instantly.

Requirements#

Functional

  • Riders request a ride from a pickup point and see a price estimate.
  • Nearby available drivers get the request; one accepts.
  • Both see each other's location live during the trip.
  • Payment happens automatically at the end.

Non-functional

  • Match a driver within seconds.
  • Location updates are processed with low latency, at high volume.
  • A driver must never be assigned two rides at once.

Estimates#

MetricEstimate
Active drivers at peak~5 million
Location updatesEvery 4 s → 1.25M updates/s
Ride requests~20M rides/day ≈ 250/s, with city peaks far higher

Location updates dominate, and they are short-lived: only the latest position matters.

Indexing locations#

Scanning every driver for each request is impossible. We need a spatial index:

  • Geohash turns latitude and longitude into a string where nearby points share a prefix. Find the rider's cell, then look at that cell and its neighbours.
  • Quadtrees split dense areas into smaller cells.
  • H3, Uber's hexagonal grid, has neighbours at equal distances, which makes radius searches and surge pricing by area cleaner.
Geohash search
Search the rider's cell and its neighbours, then filter candidates by real distance.

Architecture#

Driver app
GatewayWebSocket
Location service
Geo indexRedis, by cell
Rider app
Ride service
Matching service
Geo index
Matching service
Dispatchoffer to driver
Driver app
Ride service
Trips DB
Location service
Location streamKafka
ETA + analytics
Driver pings update an in-memory index; the matcher reads it and locks one driver per ride
  • Location service: writes each driver's latest position into an in-memory geo index (Redis GEOADD, or custom cell maps) with a short TTL, so drivers who go offline drop out automatically.
  • Matching: finds available drivers near the pickup, ranks them by ETA (road distance, not straight-line), and offers the ride to the best one.
  • Trips DB: durable trip records, payments and history in a relational database.

Matching without double-booking#

Two matchers could pick the same driver at once. Make the assignment atomic:

text
SET driver:812:lock ride:5531 NX PX 15000

Only one ride gets the lock. If the driver declines or the offer times out after about 15 seconds, the lock expires and the next driver is offered the ride.

Live trip tracking#

During a trip, the driver's location updates are forwarded to the rider over a WebSocket. Updates also go to Kafka for ETA models, fraud checks and later billing by actual route.

Partitioning by city#

Rides are local, so shard the location index and matching by city or region. Each region scales on its own, and a failure in one city doesn't affect another.

Surge pricing#

Compare demand (open requests) with supply (available drivers) per cell every minute or so, and raise prices where demand outstrips supply. This also nudges drivers toward busy areas.

Finished this walkthrough?

Mark it as read to track your progress in the list.