Design a ride-sharing platform like Uber. Riders request rides, drivers accept, and the system matches them in real time. Track driver location, display ETA, and handle surge pricing.
[Driver App]
→ location update every 5s
→ [Location Service]
→ Redis Geo (GeoHash index)
→ Kafka (location events for analytics)
[Rider App]
→ ride request
→ [Matching Service]
→ queries Redis Geo for nearby drivers
→ sends offer to selected driver
→ [Driver App] accepts
[Trip Service]
→ manages active trip state
→ streams location to rider via WebSocket
[Pricing Service]
→ calculates surge multiplier from supply/demand ratio
→ feeds pricing to Matching Service
// Driver
PUT /drivers/{driverId}/location
Body: { lat, lng, heading, speed }
PATCH /drivers/{driverId}/status { status: AVAILABLE | ON_TRIP | OFFLINE }
// Rider
POST /rides/request
Body: { riderId, pickup: {lat,lng}, destination: {lat,lng} }
Response: { rideId, driverEta, estimatedFare }
GET /rides/{rideId}/driver-location → real-time via WebSocket
// Matching
GET /drivers/nearby?lat=X&lng=Y&radius=2km&limit=10
Driver locations (Redis GEO — O(log N) geospatial queries)
GEOADD drivers:available <lng> <lat> "driver:42"
GEOSEARCH drivers:available FROMMEMBER <point> BYRADIUS 2 km ASC COUNT 10
Trips (PostgreSQL — ACID, payment reconciliation)
rides
id UUID PK
rider_id UUID
driver_id UUID
pickup POINT (PostGIS geometry)
destination POINT
status ENUM (REQUESTED, ACCEPTED, ONGOING, COMPLETED, CANCELLED)
started_at TIMESTAMP
ended_at TIMESTAMP
fare DECIMAL
Trip tracking (Cassandra — time-series location history)
trip_location
trip_id UUID PK
recorded_at TIMEUUID
lat, lng DOUBLE
Redis GEO uses GeoHash under the hood — O(log N) radius search. With 1M active drivers:
GEOSEARCH radius 2km returns results in <1mssurge_multiplier = demand / supply
where demand = ride_requests_last_10min in zone
supply = available_drivers_last_10min in zone
if surge > 1.5: show surge warning to rider