01What does the rider see first — a price before they commit?
Riders enter pickup and destination and get a fare estimate (price + ETA) before requesting the ride.
Free full guide
Design Uber — a ride-hailing platform matching riders to nearby drivers in real time, with live location tracking, pricing, and trip lifecycle management.
The interview rhythm stays compact, so the page can spend attention on the actual design decisions.
Do not only state requirements. Ask for them. Each card pairs the design constraint with a clarification question you can say out loud before drawing the architecture.
01What does the rider see first — a price before they commit?
Riders enter pickup and destination and get a fare estimate (price + ETA) before requesting the ride.
02What happens after they tap request — how fast must a match come back?
Riders request a ride at the estimated fare and get matched to a nearby available driver — or a clear failure — within about a minute.
03What does the driver side do?
Drivers go online, send location pings, receive one ride offer at a time, and accept or decline; on accept they navigate to pickup and drop-off.
04Can a rider cancel after matching, and what does the driver experience?
Yes, with grace rules: cancellation atomically releases the driver back to available, and the ride state machine records who cancelled and when.
05Does the rider watch the driver approach live?
Yes: driver location streams to the matched rider only while the ride is active - everyone else sees coarse availability, never a trackable trail.
06No driver accepts inside the matching window - then what?
The request fails clearly with retry guidance - a definite no within the minute beats a spinner that never resolves.
Out of scopeRatings (rider and driver) · Scheduled rides and ride tiers (X/XL/Comfort) · Surge pricing mechanics and payment settlement
01Can one driver ever get two rides at once?
Matching is strongly consistent: a driver holds at most one active offer or ride at a time — no double-dispatch, ever.
02How fresh do driver locations need to be?
Drivers ping every few seconds while online; proximity search may see data a few seconds old, never minutes.
03What write load should the location store plan for?
At a deliberate stress ceiling of 10M drivers online worldwide, pinging every ~5 seconds, the location store absorbs ~2M writes per second — that lives in memory, not in the relational database.
04What happens when a stadium lets out?
A burst of ~100K ride requests from one area queues and drains gracefully — nearby zones and other cities stay unaffected.
05How fast should each step feel?
Fare estimate in a couple of seconds; match (or a clear failure) within about a minute end to end.
Real interviews probe far more than a tidy list. These are the scope questions that separate candidates who interrogate the problem from those who recite it.
Treat every estimate as a pressure that justifies a component: cache, queue, partition, replica, worker pool, or fallback path.
Location write firehose
a stress ceiling of 10M drivers online worldwide × 1 ping every 5 s10,000,000 ÷ 5 ≈ 2M writes/s
No relational database absorbs this — locations go into an in-memory geo index (geohash/H3 buckets) with TTL eviction.
Proximity lookup cost
Pickup point → the geohash cell it falls in + 8 neighbor cells9 cell reads ≈ a few ms in memory
Geohashing turns "who is near me" into a handful of key lookups instead of a table scan.
Concert burst
~100K requests from one neighborhood over ~10 minutes100,000 ÷ 600 s ≈ 170 matches/s in one zone
Partition the matching queue by geo zone — the spike saturates one zone’s consumers, not the whole city.
Offer budget
Match within 60 s; each offered driver gets ~10 s to respond60 s ÷ 10 s ≈ 5-6 drivers tried before the deadline
The 10-second offer lock bounds how many candidates fit in the budget — rank candidates well, don’t spray offers.
Phantom-driver cleanup
Location entries carry a 15-30 s TTLno ping within TTL → entry expires
Drivers who crash or go offline vanish from the index on their own — no cleanup job, no offers to ghosts.
Decision example
Two very different loads share this system: about 2M location writes per second stream in from drivers, while each ride match only needs a handful of nearby candidates within a minute.
I would keep driver locations in an in-memory geo index (geohash/H3 buckets) with a short TTL, so drivers who stop pinging simply disappear. Matching pulls nearby candidates and offers the ride to one driver at a time, locking that driver for about 10 seconds — accept wins the ride, timeout or decline releases the lock and the next candidate gets the offer. Ride requests during a spike wait in a queue partitioned by area, so a stadium letting out slows that neighborhood, not the whole city.
What I would NOT do: write every location ping into the main database and scan it to find nearby drivers — 2M writes per second plus scans kills it. I also would not offer one ride to several drivers at once without a lock: two accepts arrive together and both drivers think they got the job. And I would not shard the matching system on day one — measure the per-zone rate first; premature sharding adds failure modes without adding capacity you need.
If match quality matters more than speed — pooled rides, batching — I would collect requests for a few seconds and match them in small batches instead of one at a time.
Draw the write path and the read path as separate lanes — they carry different traffic and justify different components.
Driver pings flow straight into the in-memory geo index; matching reads nearby candidates from it and offers rides one driver at a time. Ride truth lives in the database — the index is disposable.
Fare first, then request. Matching pulls a handful of nearby candidates and offers one driver at a time; the 10-second lock prevents double-dispatch and moves on automatically when a driver ignores the offer.
About 2M pings per second land in memory, bucketed into geohash/H3 cells; entries expire after 15-30 seconds so drivers who stop pinging vanish on their own.
Before optimizing, make the contract inspectable: endpoints, entities, ownership, retries, and state.
POST/fare
req{ pickup, destination }
res200 { fare_id, estimated_fare, eta }
Calls the mapping provider for route + ETA; the estimate is saved so the ride request can reference it.
POST/rides
req{ fare_id }
res201 { ride_id, state: requested } · 404 fare expired
Kicks off matching; the rider gets the match result pushed (or polls).
POST/drivers/location
req{ lat, lng }
res200
Driver identity comes from the session token, never the request body. High-frequency write straight into the geo index.
PATCH/rides/{ride_id}
req{ accept | decline }
res200 ride · 409 offer expired
Accept flips the offer atomically; decline or a 10-second timeout releases the driver and the next candidate gets the offer.
Core entities
Riderrider_id (PK) · payment_profile
Driverdriver_id (PK) · vehicle · status: offline/available/offered/on_trip
The status field is the double-dispatch guard: only an available driver can receive an offer, and the flip is atomic.
Farefare_id (PK) · pickup · destination · estimated_fare · eta
Created at estimate time; the ride request references fare_id so the quoted price cannot silently change.
Rideride_id (PK) · rider_id · driver_id · fare_id · state: requested/matched/in_progress/completed
DriverLocationdriver_id · lat/lng · updated_at
Lives in the in-memory geo index (geohash/H3 cells with a TTL), not the relational store — it is disposable data.
Pick one lane for the final third of the interview. Each lane gives you the topic, the interviewer question it should answer, and the failure mode to avoid.
FocusThe location firehose
Ask10M drivers ping every 5 seconds. Where do 2M writes per second go, and how do you answer "who is near this pickup"?
AvoidWriting pings to the main database and scanning for proximity — it dies at this rate.
FocusNever dispatch one driver twice
AskTwo ride requests want the same nearby driver at the same moment. How does exactly one win?
AvoidOffering to many drivers at once with no lock — two accepts both think they won.
FocusDriver does not answer
AskThe offered driver ignores the request. What happens at second 10, and how does the ride still match inside a minute?
AvoidBlocking the ride on one unresponsive driver instead of a lock TTL that moves on.
FocusA stadium lets out
Ask100K people request rides from one neighborhood in minutes. How do you keep the rest of the city unaffected?
AvoidOne global matching queue — a local spike becomes a citywide outage.
FocusPhantom drivers
AskA driver app crashes while marked available. How long can they still receive offers, and what cleans them up?
AvoidNo TTL on location entries — offers keep going to drivers who left an hour ago.
Talk through Uber (Ride Hailing) out loud and get AI scoring on the explanation.