Design Ride Sharing
Design a ride-sharing system like Uber or Lyft: matching, pricing, ETAs, and real-time tracking.
What is a ride-sharing system?
A ride-sharing system coordinates a time-sensitive marketplace between riders and drivers. It receives fresh driver locations, finds eligible nearby supply, commits one driver to one trip, guides both parties through a shared trip lifecycle, and settles the fare after the ride.
The hard part is not drawing cars on a map. Location data is fast, approximate, and short-lived; trip, payment, and safety decisions are durable business facts. The design must use each kind of consistency deliberately.
The core invariant is: one active accepted trip per rider and driver, with one durable owner for every accepted transition. A stale map can recover. Conflicting trip ownership cannot be exposed to users.
This walkthrough uses explicit interview assumptions rather than production claims. If you need a foundation first, review ACID transactions, message queues, and the system design interview framework.
Start with the marketplace contract
A useful first version supports one rider, one driver, and one direct trip inside a single operating region. Ask which user-visible promises matter before choosing a geo index, stream, or database.
Functional
Core rider and driver actions
- A rider requests an immediate trip, sees an estimate, and cancels when policy allows.
- An available driver publishes location, receives offers, and accepts or declines.
- Both parties see assignment, arrival, pickup, in-trip progress, and completion.
- The system calculates the final fare, starts payment, and issues a receipt.
Non-functional
Service promises
- Return an initial match outcome within 5 seconds at P95 in a healthy region.
- Keep active-trip state available during failures even if new matching is paused.
- Bound location age; never present an indefinitely stale driver as available.
- Make trip commands and payment attempts safe to retry.
Guardrails
Safety and privacy boundaries
- Isolate urgent safety reports from ordinary notification and payment capacity.
- Restrict precise-location access by role, purpose, region, and retention policy.
- Preserve auditable trip and safety events without retaining every raw coordinate forever.
- Minimize exposed contact and payment data through tokenization and scoped access.
Out of scope
First-version boundary
- No scheduled rides, shared rides, or multi-stop route optimization.
- No driver repositioning model or long-term demand forecasting.
- No globally roaming trip that changes its authoritative region mid-ride.
- No in-house card network, maps engine, or emergency-response organization.
Resolve the questions that change the architecture
- How many drivers are concurrently online? Daily active drivers do not all send location at once, so concurrency determines stream load.
- How fresh must an offer be? A four-second update interval does not imply every indexed point is four seconds old; ingestion delay, disconnects, and retries add age.
- Who owns a trip? Choose one authoritative operating region from the pickup area and keep ownership stable through completion.
- How are offers sent? Sequential offers reduce contention but can increase match time; small bounded batches improve latency but create acceptance races.
- What may degrade? New estimates and matches may pause. Active-trip recovery and the safety path require stricter continuity.
State the distinction explicitly: location is a hint used to choose candidates; an atomic trip claim is the decision that creates ownership.