#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.
#Candidate Search
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.
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.