Skip to main content
System DesignIndia Tech Careers

Design a Ride-Hailing App (Uber/Ola): System Design Interview Walkthrough

How to answer the ride-hailing system design question: location tracking, geospatial indexing, driver matching, trip state machine, pricing, ETA and the scaling issues to name.

InterviewPilot TeamOctober 17, 20264 min read

Ride hailing is a favorite at Indian product companies and global loops alike (see what Indian product companies ask). It bundles geospatial search, real-time updates and a payment flow into one design.

1. Requirements

Functional: rider requests a trip; nearby drivers are offered it; driver accepts; live tracking; fare calculation; payment; ratings. Non-functional: low-latency matching, real-time location, high availability, scale across cities, consistency in assignment.

2. Estimates

Assume 1M active drivers sending a location every 4 seconds: about 250,000 updates per second. That drives the architecture: location data goes into memory-first stores, not a transactional database.

3. Components

  • Location service: ingests driver updates (via WebSocket or lightweight HTTP/MQTT)
  • Geo index: drivers per cell, in Redis or an in-memory service
  • Matching/dispatch service: finds and ranks candidate drivers
  • Trip service: owns trip state
  • Pricing service: fare, surge
  • Payments and notification services
  • ETA/maps service (routing)

4. Geospatial indexing

Options: geohash, quadtree, S2/H3 cells. Idea: convert lat/long into a cell ID, keep a set of available drivers per cell, and search the rider's cell plus neighbors expanding outward until you have enough candidates.

5. Matching flow

  1. Rider requests a trip with pickup and drop.
  2. Pricing service returns a fare estimate.
  3. Dispatch queries nearby available drivers and ranks by ETA, rating, acceptance rate.
  4. Offer to the top driver (or a few); a timeout moves to the next.
  5. On acceptance, atomically mark the driver busy and the trip assigned.
  6. Both sides receive live updates.

6. Trip state machine

REQUESTED -> DRIVER_ASSIGNED -> ARRIVED -> IN_PROGRESS -> COMPLETED (plus CANCELLED). Guard transitions so invalid ones fail. Emit events for payments, notifications and analytics.

7. Pricing and surge

Base fare + distance + time, adjusted by a demand/supply ratio per region. A streaming job computes multipliers per cell every minute or so.

8. Reliability and follow-ups

  • Driver app loses connectivity: use last-known location and timeouts
  • Double assignment: atomic state transitions
  • Hot cities: shard by city or region
  • Payment failures: idempotent charges, retries, reconciliation
  • Fraud and safety: out-of-scope but worth a mention

Geospatial indexing in detail

Geohash encodes a location as a string whose prefix identifies a cell; nearby cells share prefixes, but neighbours across a cell boundary can have different prefixes, so you search the neighbouring cells too. H3 uses hexagonal cells with uniform neighbour distance, which makes radius searches cleaner. A quadtree subdivides dense areas more finely, which helps in cities with uneven driver density.

Practical flow: convert the rider's pickup to a cell, query that cell and its ring of neighbours for available drivers, and widen the ring until you have enough candidates.

Handling location updates

At hundreds of thousands of updates per second, you do not write each one to a database. Keep the latest position per driver in memory (Redis with geospatial support or a custom in-memory index) and sample positions into durable storage periodically for trip history and analytics.

ETA and routing

Straight-line distance is a poor proxy. Use a routing service that accounts for the road network and live traffic. For ranking many candidates quickly, do a coarse filter by straight-line distance, then compute accurate ETAs for the top few.

Dispatch strategies

StrategyIdeaTrade-off
Nearest driverOffer to the closestSimple; can starve far drivers
Batched matchingCollect requests for a few seconds and match globallyBetter overall wait time; adds latency
Offer to severalSend offers in parallel; first to accept winsFaster; complexity to cancel the rest

Mention driver acceptance timeouts (10-15 seconds) and re-offering.

Trip state and payments

Persist each transition with a timestamp and actor. Payments should be idempotent: charge once per completed trip even if the event is delivered twice. Use a ledger style record for fares, discounts and driver payouts.

Surge pricing in more detail

Compute demand (ride requests) and supply (available drivers) per cell over a sliding window. Convert the ratio into a bounded multiplier, smooth it over time to avoid flicker, and show the rider the price before they confirm. Explain that the fare quote is locked for a short period.

Interview tips

Anchor your answer in the location update load, because it justifies the memory-first design. Then walk through one trip end to end, and finish with failure cases: driver app offline, double accept, payment failure.

Frequently asked questions

Was this article useful?

Discussion

No comments yet. Been through an interview like this? Your experience could help the next candidate.

You’re posting anonymously — it appears after a quick review. Sign in to post under your name instantly.
0/2000

Bring backup into your next round.

Install InterviewPilot, upload your resume, and walk in with structured answers a keystroke away — visible to you and nobody else.