Security Notes
System Design

Design Uber (Ride Sharing)

5 min read 7 sections

DifficultyHard | HelloInterview: problem breakdown


Problem Statement

Design a ride-sharing platform where riders can request rides and drivers can accept them. The system must match riders to nearby available drivers in real time and provide live location tracking.

๐Ÿ“–

Real-world: Uber's defining technical problem is geospatial indexing at scale โ€” efficiently answering "which drivers are near this rider?" across millions of constantly-moving GPS points. Their answer became H3, the open-source hexagonal grid system they built and released, which (along with geohashes and quadtrees) is the heart of this design. The security/trust angle is unusually rich here: Uber's 2016 breach โ€” attackers found AWS credentials hardcoded in a private GitHub repo and stole 57M riders'/drivers' data โ€” became infamous because Uber paid the attackers $100K through its bug-bounty program to stay quiet and called it a "bug bounty," leading to a criminal conviction of its security chief for obstruction. It's the canonical cautionary tale for secrets-in-source and breach cover-ups โ€” a perfect thing to reference when the interviewer asks about securing the driver/rider data this system stores.


Requirements

Functional

  • Rider requests a ride with pickup + destination
  • System shows nearby available drivers
  • Driver accepts / declines rides
  • Real-time location tracking (rider tracks driver en route)
  • ETA calculation
  • Surge pricing
  • Ride history

Non-Functional

  • 15M rides/day globally โ†’ ~170 rides/s average
  • Driver location update: every 4 seconds per driver โ†’ 5M active drivers ร— 0.25/s = 1.25M location updates/s
  • Matching latency: < 3 seconds from request to match
  • Global: multiple regions, each city is semi-independent
  • High availability: can't afford downtime during peak hours

Core Design

The Two Core Challenges

Geo-proximity matching

find all drivers within N km of the rider in real-time, with locations updating continuously

Driver dispatch

select the best available driver and dispatch (bidding or assignment algorithm)

Geo-Index: Geohash

Geohashencodes a lat/lng into a base-32 string. Adjacent strings share a common prefix. Resolution scales with string length.

lat=37.7749, lng=-122.4194 (San Francisco)
  Geohash length 6: "9q8yy2"  โ†’ ~1.2 kmยฒ cell
  Geohash length 5: "9q8yy"   โ†’ ~4.8 kmยฒ cell

To find nearby drivers:
  1. Hash rider's location โ†’ geohash prefix
  2. Include 8 neighboring cells (handles cell boundary problem)
  3. Query Redis: GEOSEARCH or SET of driver IDs per geohash cell

AlternativeQuadtree โ€” recursive spatial partition. More efficient for uneven density (more cells in NYC than Montana). More complex to implement.

Production choiceUber uses S2 library (Google's spherical geometry library) which uses space-filling Hilbert curves. Redis GEO commands (GEOADD, GEORADIUS) use geohash internally.

Driver Location Store

Driver locations update every 4s. Need to:

  • Accept 1.25M writes/s
  • Query: "all drivers within 5km of (lat, lng)"
Redis (in-memory, per-region cluster):
  Key: "drivers:{geohash_prefix_5}"
  Value: sorted set of { driver_id: encoded_lat_lng }
  TTL: 30s (remove offline drivers automatically)

On each driver update:
  ZREM old_geohash_key driver_id
  ZADD new_geohash_key score(lat_lng) driver_id
  EXPIRE both keys 30s

Alternatively, use Redis GEOADD + GEORADIUS which handles this natively.


Architecture

Driver App โ†’ Location Service โ†’ Redis (geo-index, per region)
                                      โ†‘
Rider App โ†’ Matching Service โ†’ query nearby drivers from Redis
                 โ†“
          Dispatch Service โ†’ assign driver
                 โ†“
          Trip Service (Postgres) โ†’ create trip record
                 โ†“
          Notification Service โ†’ push to driver + rider
                 โ†“
          Tracking Service (WebSocket) โ†’ live location during trip

Matching Algorithm

1. Rider submits pickup location
2. Matching Service โ†’ query Redis for drivers in geohash cells around pickup
3. Filter: available=true, rating >= threshold, vehicle_type matches
4. Rank by: (distance * weight) + (acceptance_rate * weight) + (driver_score * weight)
5. Top N candidates โ†’ send ride request notification (parallel)
6. First to accept โ†’ assigned; others โ†’ cancelled
7. If no accept in 10s โ†’ expand search radius

Surge Pricing

surge_multiplier = f(demand / supply)
  demand = active ride requests in area in last 5 min
  supply = available drivers in area

Zones: geohash cells aggregated into pricing zones
If demand/supply > threshold โ†’ increase multiplier
Display to rider before confirmation

Key Design Decisions

DecisionChoiceReason
Geo-indexRedis with geohashIn-memory speed; handles 1.25M writes/s
Location updatesWrite-through to Redis onlyDon't need historical location on every update
Driver statusRedis (in-memory)Must be fast; lost on restart is OK (drivers reconnect)
Trip dataPostgreSQLACID transactions; historical queries
Real-time trackingWebSocketBidirectional, low-latency location push
Regional architecturePer-city/region clustersRide matching is local; global coordination not needed

ETA Calculation

Simple approach: distance / average_speed_for_area_and_time_of_day (historical data).

Production: integrate with mapping API (Google Maps, HERE) for real road network routing with real-time traffic.


Security Considerations

ThreatMitigation
Location spoofing by driverGPS verification; speed sanity checks (can't go 300km/h); phone sensor validation
Fake driver profileGovernment ID verification at onboarding; biometric check-in
Rider tracking abuseLocation only shared during active trip; blur precise location for finished trips
Payment fraud3DS2 for card verification; fraud ML model; velocity checks
Trip manipulationServer-side trip validation; driver cannot report impossible routes
Privacy of location historyLocation data encrypted at rest; strict retention policy; GDPR compliance
Driver impersonationUnique in-app QR code for rider to verify driver identity
Surge manipulationAnomaly detection on requests that may be fake to trigger surge

Interview Tips

Geohash vs Quadtree

know both, explain the trade-offs, and say production systems often use S2 or dedicated geo-index.

1.25M location updates/s

this number surprises people. Redis handles it because writes are O(log N) on sorted sets, and each Redis node can do 100k+ ops/s.

The "cell boundary problem"

a rider at the edge of a geohash cell might miss a driver just outside the cell. Solution: always query neighboring cells too.

Surge pricing

is a system design question in itself โ€” demand/supply ratio per zone, real-time computation.

Trip lifecycle state machine

is worth drawing: requested โ†’ accepted โ†’ en_route โ†’ arrived โ†’ in_progress โ†’ completed โ†’ rated.