🚗 Design Ride-Sharing Platform — System Design Interview Guide
Hard · Real-Time & Geospatial
Design a ride-sharing platform like Uber or Lyft that matches riders to nearby drivers in real-time, handles dynamic pricing (surge), and tracks trips end-to-end.
Open the interactive Ride-Sharing Platform design on PrepGrind → Drag load balancers, caches, databases, and queues onto a canvas, run a live traffic simulation to watch latency and bottlenecks under load, and follow the full interview walkthrough below — free, in your browser.
Functional requirements
- Riders request a ride specifying pickup and destination
- Nearby available drivers are matched to the rider
- Real-time location tracking for both rider and driver during trip
- Dynamic surge pricing based on supply/demand
- Trip history, fare calculation, and payments
- Driver and rider ratings
Non-functional requirements & scale
- 10M trips per day; 5M concurrent active drivers
- Driver location updates every 4 seconds
- Match a rider to a driver in < 1 second
- Location update ingestion: 5M drivers × 15/min = 75M writes/min
- Geospatial queries must be fast: find all drivers within 2km
- System must be highly available — no downtime during peak hours
Capacity estimation
5M active drivers sending location every 4s = 1.25M location updates/sec. Store last known location per driver. Geospatial index needed for proximity queries. Matching must complete in <1s. Surge pricing requires real-time supply/demand aggregation per cell.
Core entities
- Driver — driverId, location (lat/lng), isAvailable, vehicleType, rating, currentTripId
- Rider — riderId, location (lat/lng), paymentMethodId, rating, activeRequestId
- Trip — tripId, riderId, driverId, status, pickupLoc, dropLoc, route, fare, createdAt
- PriceEstimate — zoneId, surgeMultiplier, availableDrivers, pendingRequests, updatedAt
API design
POST /api/v1/ride-requests— Request a ride. Body: { pickupLoc, dropLoc, vehicleType }. Returns { requestId, estimatedWait, fare }.WS wss://app/trips/:tripId— Real-time trip updates: driver location, ETA, status changes.PUT /api/v1/drivers/location— Driver sends location update. Body: { lat, lng, heading, speed }.POST /api/v1/trips/:id/complete— End trip. Triggers fare calculation and payment.
High-level design
Drivers push location to Location Service → stored in Redis Geo. Rider requests ride → Matching Service queries Redis Geo for nearby drivers → ranks by ETA → sends offer to driver via WebSocket → driver accepts → Trip created.
Deep dives
📍 Geospatial Indexing
Redis GEOADD stores driver lat/lng. GEORADIUS returns drivers within N km in O(N+log M). Alternative: S2 Geometry (Google) — divides earth into hierarchical cells. Each driver location → cell ID. Proximity search = query nearby cells. Uber uses H3 hexagonal grid. Key insight: convert 2D problem to 1D string prefix matching.
🤝 Matching Algorithm
Step 1: GEORADIUS to get candidates within 2km. Step 2: filter available drivers (isAvailable=true). Step 3: rank by estimated ETA (Google Maps API or internal routing). Step 4: send offer to best driver. If no accept in 8s, try next. Use distributed lock (Redis SETNX) to prevent double-booking same driver.
💰 Surge Pricing
Kafka streams location events → Flink aggregates demand (requests) vs supply (available drivers) per H3 cell per minute. Surge multiplier = f(demand/supply). Redis stores multiplier per cell with 1-minute TTL. Price estimate API reads from Redis. Challenge: must be consistent — rider sees same price until they confirm.
📡 Real-Time Tracking
Driver sends location every 4s over persistent WebSocket. Server broadcasts to rider's WS connection. Use Redis Pub/Sub to route between servers. Trip WebSocket channel = topic. During active trip: ~15 location events/min per active trip × 300K concurrent trips = 4.5M events/min.
Scaling considerations
- Redis Cluster for geo index, sharded by city/region to keep queries local
- Separate Location Service (write-heavy, 1.25M/sec) from Matching Service (read-heavy)
- Kafka partitioned by cityId for surge pricing stream processing
- Circuit breaker around external routing API (Google Maps) with cached fallback
- Database: PostgreSQL for trips (ACID), Cassandra for location history (write-heavy)
What interviewers expect by level
- Junior: Describe request flow: rider requests → find nearby drivers → match → start trip. Know Redis for location storage.
- Mid: Redis GEOADD/GEORADIUS, WebSocket for real-time tracking, distributed lock for driver assignment.
- Senior: H3/S2 geospatial indexing, Kafka + Flink surge pricing, matching algorithm with ETA ranking, handling driver cancellations.
- Staff: Multi-region deployment with city sharding, ETA model serving (ML), cost model for 1.25M loc updates/sec, graceful degradation.
Practice more system design case studies
- Design URL Shortener
- Design Social Media Feed
- Design Chat System
- Design Video Streaming
- Design E-Commerce Platform
- Design UPI Payment Gateway
- Design Google Docs
- Design Tinder
- Design Google Drive / Dropbox
- Design Instagram
- Design Type-Ahead Search
- Design Web Crawler
- Design Ticket Booking (BookMyShow)
- Design Pastebin
- Design Notification System
- Design Rate Limiter (Standalone)
- Design Simple Web App
- Design Food Delivery (Swiggy)
- Design Stock Trading System
- Design Live Streaming (Twitch)
- Design Distributed Key-Value Store
- Design Ad Click Aggregation
- Design Monitoring / Metrics (Datadog)
- Design Online Judge (LeetCode)
- Design FB Post Search
- Design Yelp
- Design Cache Layer
- Design Message Queue
- Design Full Production Stack
PrepGrind runs entirely in your browser, free, no installation required. Loading the interactive playground…