Skip to main content
Articles/System Design/system-design-hld-ride-sharing-example
Scenario Article

System Design HLD Example: Ride-Sharing (Uber/Lyft)

1. Use Cases & Requirements

Abstract Algorithms•Mar 28, 2026
💡 Executive Summary

A ride-sharing platform is a high-velocity geospatial matching engine.

🎯 System Scenario & Requirements

System Goal

A ride-sharing platform is a high-velocity geospatial matching engine.

Actors & Components

  • Mobile Real-time Clients
  • Geospatial & Matching
  • Location State & Dispatches
  • Driver Mobile App
  • Passenger App
  • WebSocket Gateway
  • Location Service
  • Matching Engine

Functional Requirements

  • TLDR: A ride-sharing platform is a high-velocity geospatial matching engine.
  • Drivers stream GPS coordinates every 5 seconds into a Redis Geospatial Index .
  • When a rider requests a trip, the Matching Service executes a GEORADIUS query to find the closest available drivers.

Constraints & Assumptions

  • Choosing the right components requires balancing performance against consistency constraints.
  • Transport Protocols: WebSockets vs SSE vs HTTP Polling WebSockets: Full-duplex transport, low overhead.

⚡ Execution Stages & Decision Trace

1

Stage 1 — 2. Capacity Estimations & Scale Goals

Action / Decision:

Let's compute our core storage, throughput, and memory requirements to establish concrete design scale goals: Although 50 MB is small enough to fit on a single caching instance, 100,000 writes/sec reaches the operationa…

Component Behavior:

This dictates that we must partition or shard our caching layers horizontally to scale write throughput rather than storage capacity.

Observable Output: Key Takeaway: Design distinct scaling models for the 100k QPS location ingestion path and the 500 QPS transaction path.
Read Full Stage in Deep Dive ↓
📖

Deep Dive

Detailed Architectural Analysis

Scenario context

A ride-sharing platform is a high-velocity geospatial matching engine. Drivers stream GPS coordinates every 5 seconds into a Redis Geospatial Index. When a rider requests a trip, the Matching Service executes a GEORADIUS query to find the closest available drivers. A distributed Trip State Machine ensures transactional consistency (no double-matching), while WebSockets provide the real-time "car on map…

This walkthrough focuses on 1. Use Cases & Requirements.

Before making a design choice, clarify:

  • Imagine it’s New Year's Eve in New York City.
  • At 12:05 AM, one million people open their ride-sharing apps simultaneously.
  • In the background, 50,000 drivers are moving through the city, sending GPS updates every few seconds.

Concepts in play: system-design-hld-architectures, caching, database-indexing, event-driven-architecture

Stage 1 — 2. Capacity Estimations & Scale Goals

  • Let's compute our core storage, throughput, and memory requirements to establish concrete design scale goals: Although 50 MB is small enough to fit on a single caching instance, 100,000 writes/sec reaches the operationa…
  • This dictates that we must partition or shard our caching layers horizontally to scale write throughput rather than storage capacity.
  • Key Takeaway: Design distinct scaling models for the 100k QPS location ingestion path and the 500 QPS transaction path.

Observable outcome: Key Takeaway: Design distinct scaling models for the 100k QPS location ingestion path and the 500 QPS transaction path.

Stage 2 — 3. High-Level Design (HLD)

  • The high-level design establishes the platform's architectural system boundary and separates the volatile, write-heavy driver tracking path from the durable, transactional matching and trip lifecycle database.
  • System Boundary & Context Model External actors (Riders, Drivers) and third-party integrations (Maps, Payments, Notifications) connect through well-defined edge boundaries to the core system services: High-Level Subsyst…
  • Location Ingestion Service: Processes 5s driver GPS location broadcasts and pushes them to Redis and Kafka.
  • Redis Geospatial Cache: Maintains the real-time localized index of available drivers.
graph TD
    Driver -->|GPS 5s| LS[Location Service]
    LS -->|GEOADD| Redis[(Redis Geo Index)]

    Rider -->|Request Ride| MS[Matching Service]
    MS -->|GEORADIUS| Redis
    MS -->|Lock Driver| TS[Trip Service]
    TS --> DB[(Trip DB: Postgres)]

    TS -->|Match Event| NS[Notification Service]
    NS -->|Push| Driver
    NS -->|Push| Rider

    LS -->|Stream| WS[WebSocket Gateway]
    WS -->|Live Update| Rider

Observable outcome: Redis Geospatial Cache: Maintains the real-time localized index of available drivers.

Stage 3 — 4. Detailed Design: Location Ingestion & Geohashing

  • A traditional relational database with a B-tree index cannot execute two-dimensional range queries efficiently under heavy load.
  • To solve this, the Location Service leverages Geohashing .
  • The Mechanics of Geohashing Geohashing partitions the Earth's surface into a hierarchical grid of cells.
  • Each grid cell is represented by a unique base-32 string.

Observable outcome: Each grid cell is represented by a unique base-32 string.

Stage 4 — 5. Detailed Design: Matching Engine & Distributed Locking

  • A core correctness invariant is that a driver must never be matched to two riders at the same time .
  • Double-booking is a catastrophic user experience failure.
  • Candidate Discovery: The Matching Service queries GEORADIUS to find available drivers within a 2km radius.
  • Lock Acquisition: For each candidate, the service attempts to acquire an atomic distributed lock in Redis: 3.
    const acquired = await redis.set(`driver_lock:${driverId}`, 'locked', 'NX', 'PX', 15000);

Observable outcome: Lock Acquisition: For each candidate, the service attempts to acquire an atomic distributed lock in Redis: 3.

Stage 5 — 6. Detailed Design: WebSocket Gateway Fleet & Real-Time Updates

  • Pings from active drivers must be streamed live to the matched rider's map display to provide the expected real-time tracking experience.
  • Gateway Scalability At a scale of 1 million concurrent riders, maintaining WebSocket connection states on a single instance is impossible.
  • We scale this horizontally: Stateless Gateways: A fleet of WebSocket gateway nodes holds open TCP connections with client apps.
  • Redis Pub/Sub Backplane: When the Location Service receives a driver update, it publishes the coordinate packet to Redis Pub/Sub on channel trip:ws:${riderId} .

Observable outcome: Redis Pub/Sub Backplane: When the Location Service receives a driver update, it publishes the coordinate packet to Redis Pub/Sub on channel trip:ws:${riderId} .

Stage 6 — 7. Database Schema & Data Models

  • Relational databases handle durable state transactions, while Redis sharding handles rapid geospatial index reads.
  • Relational Tables (PostgreSQL) Driver Profile Table driver id (UUID, PK) status (ENUM: OFFLINE, AVAILABLE, ON TRIP) vehicle type (VARCHAR: UberX, UberXL, Black) rating (DECIMAL) city id (VARCHAR) Trip Ledger Table trip…

Observable outcome: Relational Tables (PostgreSQL) Driver Profile Table driver id (UUID, PK) status (ENUM: OFFLINE, AVAILABLE, ON TRIP) vehicle type (VARCHAR: UberX, UberXL, Black) rating (DECIMAL) city id (VARCHAR) Trip Ledger Table trip…

End-to-end outcome

After working through the stages, you should be able to explain:

  • Architecture Cheat Sheet Location Ingestion: Mobile App $\rightarrow$ API Gateway $\rightarrow$ Kafka $\rightarrow$ consumer writes to Redis Geo Index.
  • Matching Flow: Rider requests match $\rightarrow$ execute GEORADIUS $\rightarrow$ acquire Redis NX lock $\rightarrow$ write trip record to Postgres $\rightarrow$ notify driver.

Alternatives considered

The source focuses on one primary design. A second architecture is not compared, so no alternative is invented here.

Failure and degraded modes

Choosing the right components requires balancing performance against consistency constraints.

  • Detection: Choosing the right components requires balancing performance against consistency constraints.
  • User or operator impact: Choosing the right components requires balancing performance against consistency constraints.

Transport Protocols: WebSockets vs SSE vs HTTP Polling

  • Detection: WebSockets: Full-duplex transport, low overhead.
  • User or operator impact: WebSockets: Full-duplex transport, low overhead.

Spatial Storage: Redis vs PostGIS vs Cassandra

  • Detection: Redis ZSET: In-memory, sub-millisecond lookups.
  • User or operator impact: Redis ZSET: In-memory, sub-millisecond lookups.

Share this case study

Discuss architecture trade-offs and lessons with your team.

Share:XLinkedInReddit