Ride Matching and Dispatch

Combining nearby-driver search with atomic reservation and offer timeouts

S
System Design Sandbox··10 min read
Learn how ride-sharing systems match riders to drivers. Covers geospatial candidate search, ETA ranking, atomic driver reservation, dispatch leases, ride and driver state machines, and double-assignment prevention.

#Introduction

A rider requests a car. Two drivers are nearby. Five other riders request at the same time.

The hard part is not finding a nearby driver. The hard part is assigning exactly one available driver to exactly one rider while everyone is moving.

Ride matching is a geospatial search problem plus a consistency problem.

This article supports the Ride-Sharing Service solution. Read it with High-Write Location Tracking and Regional Routing and Geo-Partitioning to get the full Uber-style design.


Start with location.

The matching service queries a geospatial index for available drivers around the pickup point:

pickup location
  -> covering cells
  -> candidate drivers
  -> exact distance / ETA filter
  -> ranked candidate list

Candidate ranking can include:

  • distance to pickup
  • estimated arrival time
  • driver acceptance rate
  • vehicle type
  • rider preferences
  • driver workload
  • surge or marketplace constraints

The first result is not automatically assigned. It becomes the first candidate to reserve. This is the key difference between a read-heavy local search system like Proximity Service and a transactional marketplace like Ride-Sharing Service.


#Driver Reservation

The double-booking bug happens here.

If two ride requests pick the same driver from the geo index, the system needs an atomic reservation:

UPDATE drivers
SET state = 'reserved', reserved_ride_id = :rideId
WHERE driver_id = :driverId
  AND state = 'available'

Only one request should win. The loser moves to the next candidate. This is the same kind of "final state transition must be strong" reasoning covered in Consistency Patterns and Distributed Transactions, though most ride systems try to keep the transaction scoped to one regional market.

Ride Request
Nearby Driver Index
ETA Ranker
Driver Lease
Dispatch Offer
Ride State Machine

The reservation should have a short lease. If the driver does not accept within the timeout, release the driver and try another candidate. Offer delivery usually uses WebSockets, push notifications, or a dispatch stream.


#Dispatch State Machine

Rides and drivers should move through explicit states.

Ride states:

requested -> matching -> offered -> accepted -> arriving -> in_progress -> completed

Driver states:

available -> reserved -> en_route_pickup -> on_trip -> available

State transitions should be validated. A driver should not move from available directly to on_trip without an accepted ride. A ride should not be accepted by a driver whose reservation expired.

This is where strong consistency matters. Marketplace search can tolerate stale candidates. Final assignment cannot.


#Common Interview Mistakes

Mistake 1: Treating nearest driver as assigned.

Nearest driver is only a candidate. Assignment requires an atomic reservation.

Mistake 2: Ignoring reservation expiry.

Drivers reject, disconnect, or time out. Leases keep the marketplace from getting stuck.

Mistake 3: Updating driver and ride state in different unreliable paths.

Use a transaction or a state-machine service that owns assignment consistency.

Mistake 4: Ranking only by distance.

ETA, acceptance likelihood, vehicle class, and marketplace balance can matter more than raw distance.


#Summary: What to Remember

Ride matching is candidate search plus atomic dispatch.

Use a geo index to find nearby available drivers, rank candidates, reserve one driver with a conditional write or transaction, and drive the ride through explicit states. Stale search results are acceptable. Double assignment is not.

Related articles: High-Write Location Tracking, Geospatial Indexing, Regional Routing and Geo-Partitioning, Consistency Patterns, and Design a Ride-Sharing Service.