← Back to all questions
Senior / StaffReal-TimeGeospatial

Design Real-Time GPS Tracking

A senior-to-staff walkthrough of a real-time location pipeline that ingests 1.25M GPS updates per second from 5M drivers, serves live positions for matching, and streams each driver's movement to the rider tracking their trip. It trades update frequency against battery and bandwidth, separates live location (Redis GEO) from durable history (Cassandra), and leans on client-side interpolation to make 4-second updates look continuous. Follow it top to bottom, or jump to any step.

Level
Senior / Staff
Category
Real-Time · Geospatial
Interview time
45 min
100% free · No login required
WHAT THIS QUESTION TESTS
·Sustains 1.25M updates/sec with client batching and movement-based dedup
·Redis GEO radius queries power nearby-driver matching
·Cassandra history partitioned by driver and date with a 90-day TTL
·WebSocket fan-out delivers live location to the rider on an active trip
★ STAFF-LEVEL SIGNALS
Separates the live-location store from the history store instead of forcing one database to do both
Partitions Kafka by city and shards hot cities into zones to avoid geospatial hotspots
Pushes smoothing to the client with heading-aware interpolation rather than raising update frequency
Reasons through HTTP vs UDP vs MQTT under lossy-OK location semantics
1

Requirements

Functional Requirements

  • Ingest location updates: Receive GPS coordinates from millions of drivers every 4 seconds
  • Real-time delivery: Push driver location to riders tracking their trip
  • Location history: Store GPS traces for trip reconstruction, analytics, fraud detection
  • Geospatial queries: Find nearby drivers (for matching), compute distances
  • Map rendering: Display driver movement on client maps with smooth animation

Non-Functional Requirements

  • Throughput: Handle 1.25M location updates/second (5M drivers × 1/4s)
  • Latency: Location visible to rider within 1-2 seconds of driver's GPS reading
  • Storage: Retain location history for 90 days (compliance, analytics)
  • Availability: 99.9% for ingestion, 99.99% for delivery to riders
2

Back-of-envelope estimation

Metric
Estimate
Active drivers
5M
Location updates/sec
1.25M
Update payload size
100 bytes (lat, lng, heading, speed, timestamp, driver_id)
Ingestion bandwidth
1.25M × 100B = 125 MB/s
Location records/day
1.25M × 86,400 = ~108B records/day
Storage/day (raw)
108B × 100B = ~10 TB/day
With compression (5x)
~2 TB/day
90-day retention
~180 TB
3

High-level architecture

┌──────────────┐ HTTP/UDP ┌──────────────────┐
│ Driver App │─────────────▶│ Location │
│ (GPS every 4s)│ │ Ingestion │
└──────────────┘ │ Service │
└────────┬─────────┘
┌────┴────┐
│ Kafka │
│ (events)│
└────┬────┘
┌───────────────────┼───────────────────┐
│ │ │
┌─────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
│ Redis GEO │ │ Cassandra │ │ Trip │
│ Consumer │ │ Consumer │ │ Tracker │
│ (current │ │ (history) │ │ Consumer │
│ location) │ │ │ │ (push to │
└─────┬──────┘ └─────────────┘ │ riders) │
│ └──────┬─────┘
┌─────┴──────┐ │
│ Redis GEO │ ┌──────┴──────┐
│ (matching │ │ WebSocket │
│ queries) │ │ Gateway │
└────────────┘ │ (→ rider) │
└─────────────┘

Data Flow: Driver Location Update to Rider’s Screen

1. Driver app reads GPS → batches 1-2 readings → sends HTTP POST

2. Location Ingestion Service validates, enriches (add city_id), publishes to Kafka

3. Redis consumer: Updates GEOADD available_drivers:{city} driver_id lng lat (for matching)

4. Cassandra consumer: Writes to location_history table (for analytics/compliance)

5. Trip Tracker consumer: If driver is on an active trip:

  • Look up rider's WebSocket connection in Redis
  • Push location update to rider's WebSocket Gateway
  • Gateway delivers to rider's app

1. Rider app: Receives update → animates driver marker smoothly between previous and new position (client-side interpolation between 4-second updates)

4

Deep dives

WHERE STAFF IS WON

Deep Dive 1: Client-Side Smooth Animation

Problem: GPS updates arrive every 4 seconds. Without interpolation, the driver marker “teleports” every 4 seconds.

Solution: Client-side animation interpolation.

On new GPS point received (lat2, lng2, heading2, speed):
animate driver marker from (lat1, lng1) to (lat2, lng2) over 4 seconds
use cubic Bézier curve considering heading for realistic path
if no update in 8 seconds: stop animation, show "Updating location..."

This creates the illusion of smooth, continuous movement even with 4-second update intervals.

Deep Dive 2: Ingestion Optimization

Batching on client: Driver app collects 2-3 GPS readings, sends as single request. Reduces connection overhead by 60%.

Deduplication: If driver hasn’t moved > 5 meters since last update, don’t send (parked/idle). Reduces traffic by ~30% during idle periods.

Protocol choice:

Protocol
Pros
Cons
Use Case
HTTP
Reliable, firewall-friendly
Higher overhead per message
Default
WebSocket
Bidirectional, lower overhead
Stateful connection management
When bidirectional needed
UDP
Lowest overhead, fire-and-forget
No delivery guarantee
Location updates (OK to lose occasional)
MQTT
Lightweight, pub/sub built-in
Requires MQTT broker
IoT-style scenarios

Uber’s choice: HTTP with batching for reliability. Accept slightly higher overhead because location data is critical for matching and tracking.

Deep Dive 3: Geospatial Storage and Queries

Redis GEO for current locations:

GEOADD drivers:san_francisco driver_123 -122.4194 37.7749
GEORADIUS drivers:san_francisco -122.4194 37.7749 5 km WITHCOORD COUNT 50 ASC
  • Under the hood: sorted set with geohash as score
  • O(N+log(M)) for radius query where N = returned results, M = total entries
  • Memory: 5M drivers × ~100 bytes = ~500 MB (fits in single Redis)

Cassandra for location history:

Partition key: (driver_id, date)
Clustering key: timestamp DESC
Columns: lat, lng, speed, heading, accuracy, trip_id
  • Write-optimized (LSM tree)
  • Time-series access pattern (query driver's route for a specific trip/date)
  • TTL: 90 days (auto-cleanup)
5

Bottlenecks & tradeoffs

Bottlenecks

1. Kafka throughput: 1.25M events/sec requires significant Kafka cluster

  • Mitigation: 500+ partitions, partition by city_id for locality

1. Redis GEO hot cities: NYC/SF may have 500K drivers → hot partition

  • Mitigation: Split large cities into zones, each with own Redis key

1. WebSocket connections: 2M concurrent trips × 2 users = 4M WebSocket connections

  • Mitigation: Horizontal WebSocket gateway fleet, sticky sessions

Key Tradeoffs

Decision
Option A
Option B
Choice
Update frequency
1s (smooth, battery drain)
4s (efficient)
4s (industry standard)
Protocol
HTTP (reliable)
UDP (fast, lossy)
HTTP with batching
Current location store
PostgreSQL
Redis GEO
Redis GEO (speed)
History store
PostgreSQL
Cassandra (time-series)
Cassandra (write throughput)
Client animation
Discrete jumps
Interpolated smooth
Interpolated

Monitoring

  • Location update lag: Time from GPS reading to Redis update — alert if > 5s
  • Kafka consumer lag: Alert if processing falls behind > 10s
  • Redis GEO query latency: Alert if > 10ms
  • WebSocket delivery rate: Alert if < 95% of updates delivered
  • GPS accuracy distribution: Track % of low-accuracy readings

Rubric — Senior vs Staff

Dimension
Senior signal
Staff signal
Ingestion
Accepts updates and writes them through a queue.
Batches and dedups on the client, partitions Kafka by city, and quantifies the bandwidth saved.
Geospatial store
Uses Redis GEO for nearby-driver lookups.
Splits hot cities into zones and justifies Redis GEO over PostgreSQL on latency and memory footprint.
History storage
Persists traces to a database with a TTL.
Picks Cassandra for write-heavy time-series, designs the partition and clustering keys, and sets 90-day expiry.
Real-time delivery
Pushes location to riders over WebSockets.
Sizes a multi-million-connection gateway fleet with sticky sessions and a delivery-rate SLO.
Client experience
Animates the marker between points.
Interpolates with heading-aware curves and degrades gracefully when updates stall.
★ MORE WALKTHROUGHS

Want more breakdowns like this?

Join free early access for upcoming RAG, LLM eval, agents, and AI infrastructure walkthroughs.

Join Free Early Access →