Skip to content
AI360Xpert

Ride Sharing Service

Intermediate

Overview

A ride-sharing service matches riders requesting trips with nearby available drivers, then tracks the trip in real time until completion. The core challenges are ingesting a continuous stream of driver location updates and answering low-latency geospatial "nearest driver" queries at city scale.

High-level architecture for Ride Sharing Service
High-level architecture for Ride Sharing Service

Functional Requirements

  • Riders request a ride from a pickup to a destination; the system matches a nearby driver.
  • Drivers continuously report their location and availability.
  • Track the trip in real time and update both parties (driver en route, in progress, complete).
  • Compute fare estimates and finalize payment at trip end.

Non-Functional Requirements

  • Low latency: matching should complete within a few seconds.
  • High availability: the matching and tracking paths must stay up regionally.
  • Accurate, fresh location data with frequent updates.
  • Consistency for trip state transitions (a trip has exactly one assigned driver).

Capacity Estimation

Assume 10M active drivers, each sending a location update every 4 seconds, and 5M rides/day.

  • QPS:
    • Location updates: 10M / 4 s = 2.5M updates/sec - the dominant write load.
    • Ride requests: 5M / 86,400 s ~ 58 requests/sec (peak ~10x ~ 580/sec).
  • Storage:
    • Live locations are mostly hot state in memory: 10M x ~100 B ~ 1 GB resident.
    • Trip records ~ 1 KB each: 5M x 1 KB = 5 GB/day -> ~1.8 TB/year of durable trip history.
  • Bandwidth: location ingress 2.5M/s x 100 B ~ 250 MB/s; matching/tracking egress is comparatively small.

High-Level Architecture

The system is heavily split between a high-write Location Tracking Service (managing driver pings in memory) and a highly consistent Trip Management Service (managing ride state in a database). An intelligent Dispatch Service connects the two by querying the Location Service for drivers and managing the offer-acceptance flow.

Data Model

EntityFields / SchemaStorage Choice
driver_location
driver_id, lat, lng, geohash, updated_at, status
In-memory geo index (Redis or custom C++ service), sharded by geohash cell
trip
trip_id (PK), rider_id, driver_id, state, pickup, dropoff, fare
Relational / strongly-consistent store (PostgreSQL)
driver
driver_id (PK), vehicle, rating
Relational store
trip_event
trip_id, ts, event_type, location
Append-only event store (Cassandra)

Detailed Design

Location Ingest and Geo-Indexing

The 2.5M updates/sec are absorbed by a stateless Location Ingest tier that writes into an in-memory geospatial index (like a Quadtree) partitioned by region. Sharding by geographic cell keeps each node responsible for a bounded region and spreads the write load. Consistent hashing maps cells to nodes so the cluster can grow or shrink. Locations are hot, high-churn state, so they live in memory rather than a disk database, because updating a DB row 2.5 million times a second will destroy the disk.

Matching (The Dispatch Service)

A ride request computes the rider's geohash, queries the Location index for the neighboring cells, gathers candidate drivers, and ranks them by ETA (using a routing engine, not just a straight line). It offers the trip to the best candidate.

State Machine & Consistency

The trip's state transitions (requested -> assigned -> in_progress -> completed) are written to a strongly consistent relational database so a driver is never double-assigned. The Dispatch Service uses optimistic locking when offering a ride to a driver to ensure no other rider claims that driver concurrently.

Bottlenecks & Solutions

Maintaining WebSockets for 10M active drivers to receive real-time dispatch offers is a major bottleneck requiring a massive connection gateway tier. Furthermore, if a stadium lets out, thousands of riders in the exact same geohash will request rides simultaneously, creating a "hot shard" on the Location Index node responsible for that area.

Interview Follow-up Questions

Q: How do you handle the 'hot shard' problem when a stadium empties?

We use a combination of dynamic cell splitting and caching. For extremely dense areas, we can temporarily subdivide the geographic cell (e.g., using a finer-grained geohash) and distribute it across multiple nodes. The dispatch service can also batch requests to reduce the load on the location index.

Q: What happens if a driver drives into a tunnel and loses connection during a trip?

The driver's app buffers location updates locally. The Trip Management service relies on the driver's phone as the source of truth for the route driven. When they exit the tunnel, the app flushes the batched coordinates to the server so the fare can be calculated correctly based on the actual distance traveled.

Q: Why not use a standard database like PostgreSQL for driver locations?

Writing 2.5 million rows per second to a relational database is impossible without massive, expensive sharding. Because driver locations are ephemeral (we only care about the latest one for matching, older ones can be written asynchronously to cold storage for analytics), an in-memory grid is the only cost-effective way to handle the write volume.