Skip to main content
SDMastery
hard9 min readUpdated 2026-06-03

Design Uber

System design interview solution for Design Uber. Includes requirements, API design, data model, architecture, scaling strategy, and tradeoffs.

Design Uber system design overview showing key components and metrics
High-level overview of Design Uber

Problem Statement

Design a system similar to Uber. The system should handle millions of users and provide a reliable, scalable experience.

Step 1: Clarifying Questions

Before diving into the design, ask these clarifying questions:

  • What is the expected scale (users, requests per second)?
  • What are the most critical features to support?
  • What are the latency requirements?
  • Do we need to support real-time features?
  • What consistency guarantees are needed?

Step 2: Functional Requirements

Design Uber system architecture with service components and data flow
System architecture for Design Uber
  1. Core feature set for Uber
  2. User-facing APIs and interactions
  3. Data storage and retrieval
  4. Search and discovery (if applicable)
  5. Notifications (if applicable)

Step 3: Non-Functional Requirements

  • Scalability: Handle millions of concurrent users
  • Availability: 99.99% uptime (four nines)
  • Latency: Sub-200ms for read operations
  • Consistency: Eventually consistent where acceptable, strongly consistent for critical paths
  • Durability: No data loss

Step 4: Back-of-the-Envelope Estimation

MetricEstimate
Daily Active Users10M
Read:Write Ratio10:1
Average Request Size1 KB
Storage per year~10 TB
Peak QPS100K

Step 5: API Design

text
POST /api/v1/resource
GET  /api/v1/resource/{id}
PUT  /api/v1/resource/{id}
DELETE /api/v1/resource/{id}
Step-by-step diagram showing how Design Uber works in practice
How Design Uber works step by step

Step 6: Data Model

Define the core entities and their relationships. Consider the access patterns when choosing between SQL and NoSQL.

Step 7: High-Level Architecture

The system consists of these major components:

  1. Client Layer — Web/mobile clients
  2. API Gateway — Rate limiting, authentication, routing
  3. Application Servers — Business logic
  4. Database Layer — Primary storage
  5. Cache Layer — Redis/Memcached for hot data
  6. Message Queue — Async processing

Step 8: Detailed Component Design

Data flow diagram for Design Uber showing request and response paths
Data flow through Design Uber

Write Path

How data flows from client to persistent storage.

Read Path

How data is retrieved, including cache interactions.

Step 9: Scaling Strategy

  • Horizontal scaling of application servers behind a load balancer
  • Database sharding by user ID or geographic region
  • Read replicas for read-heavy workloads
  • CDN for static content delivery
  • Auto-scaling based on traffic patterns

Step 10: Reliability and Fault Tolerance

Interview tips for Design Uber system design questions
Interview tips for Design Uber
  • Data replication across availability zones
  • Circuit breakers for dependent services
  • Graceful degradation under high load
  • Health checks and automated failover

Step 11: Monitoring and Observability

  • Request latency (p50, p95, p99)
  • Error rates by endpoint
  • Database query performance
  • Cache hit/miss ratios
  • Queue depth and processing lag

Key Tradeoffs

DecisionOption AOption BChosen
DatabaseSQLNoSQLDepends on access patterns
ConsistencyStrongEventualEventual for most reads
CommunicationSyncAsyncAsync for non-critical paths

How to Present This in an Interview

Decision guide showing when to use Design Uber and when to avoid
When to use Design Uber
  1. Start with clarifying questions (2 min)
  2. Define requirements (3 min)
  3. Do estimation (2 min)
  4. Design API and data model (5 min)
  5. Draw high-level architecture (10 min)
  6. Deep dive into critical components (10 min)
  7. Discuss tradeoffs and bottlenecks (5 min)

Practical Implementation for .NET Developers

In a .NET application, you would typically implement this pattern using the following approach:

ASP.NET Core setup: Create a service class that encapsulates the logic, register it with dependency injection, and inject it into your controllers or minimal API endpoints. The built-in DI container handles lifecycle management.

Entity Framework Core: For database interactions, EF Core provides the ORM layer. Use migrations for schema management and raw SQL for performance-critical queries. Consider Dapper for read-heavy paths where EF Core's overhead matters.

Pros and cons analysis of Design Uber for system design decisions
Advantages and disadvantages of Design Uber

Azure integration: If deploying to Azure, leverage managed services — Azure Cache for Redis, Azure SQL, Azure Service Bus, Azure Cosmos DB. These eliminate operational overhead and provide built-in monitoring through Application Insights.

Testing: Use xUnit with Testcontainers for integration tests that spin up real databases in Docker. Mock external dependencies with NSubstitute. The WebApplicationFactory class lets you test your entire HTTP pipeline in-process.

Monitoring: Add Application Insights telemetry to track request latency, dependency calls, and custom metrics. Use structured logging with Serilog to make production debugging possible:

text
Log.Information("Processing order {OrderId} for {CustomerId}", orderId, customerId);

This gives you searchable, structured logs in Azure Monitor or Seq.

Real-world companies using Design Uber in production systems
Real-world examples of Design Uber

Deep-Dive: Clarifying Questions for Uber

  1. What geographic coverage? Global (900+ cities) or a single city? Global requires geo-distributed architecture with regional data residency.
  2. How do we match riders to drivers? Nearest available driver? Best ETA? Consider traffic, driver rating, surge pricing? The matching algorithm is the core intellectual property.
  3. What is the location update frequency? Drivers send GPS updates every 3-4 seconds. With 5 million active drivers, that is 1.25-1.67 million location updates per second.
  4. Do we need surge pricing? Dynamic pricing based on supply/demand ratio requires real-time market-making computation.
  5. What geospatial indexing do we use? Google S2, Uber H3, or traditional geohashing? This choice affects query efficiency and precision.
  6. How do we handle real-time tracking? Riders need to see their driver approaching in real-time. This requires pushing location updates to specific rider apps via WebSocket connections.

Specific Functional Requirements

  1. Ride Request: Rider specifies pickup and dropoff locations, selects ride type (UberX, XL, Black), sees price estimate
  2. Driver Matching: System matches the rider with the best available driver based on ETA, proximity, and other factors
  3. Real-Time Tracking: Both rider and driver see each other's location updating in real-time during the ride
  4. ETA Estimation: Predict pickup time and trip duration using historical traffic data, real-time conditions, and road graphs
  5. Surge Pricing: Dynamically adjust prices based on local supply (available drivers) and demand (ride requests) ratios
  6. Payment Processing: Automatically charge the rider after trip completion with fare breakdown
  7. Rating System: Both riders and drivers rate each other after each trip

Specific API Endpoints

text
POST /api/v1/rides/estimate
  Body: { "pickup": { "lat": 37.7749, "lng": -122.4194 }, "dropoff": { "lat": 37.3382, "lng": -121.8863 }, "ride_type": "uberx" }
  Response: { "estimated_fare": "$23-28", "estimated_pickup": "4 min", "estimated_trip": "42 min", "surge_multiplier": 1.0 }

POST /api/v1/rides/request
  Body: { "pickup": {...}, "dropoff": {...}, "ride_type": "uberx", "payment_method_id": "pm_abc" }
  Response: { "ride_id": "ride_123", "status": "matching", "driver": null }

WebSocket /ws/rides/:ride_id/track
  Messages: { "type": "location_update", "lat": 37.77, "lng": -122.41, "heading": 180, "eta_seconds": 120 }

PUT /api/v1/drivers/location
  Body: { "lat": 37.7749, "lng": -122.4194, "heading": 90, "speed": 35 }
  (Called every 3-4 seconds by driver app)
Comparison table for Design Uber showing key metrics and tradeoffs
Comparing key aspects of Design Uber

Specific Data Model

Driver Location Store (Real-time): Use an in-memory geospatial index. Uber uses H3 hexagonal grid cells: driver locations are indexed by H3 cell ID (resolution 7, approximately 5 km2 hexagons). When a ride request comes in, search the pickup location's H3 cell and adjacent cells for available drivers.

StoreKeyValue
Driver Locations (Redis)h3_cell_idSet of (driver_id, lat, lng, status, last_updated)
Active Rides (PostgreSQL)ride_idrider_id, driver_id, pickup, dropoff, status, fare, timestamps
Driver Profilesdriver_idname, vehicle, rating, documents, status
Trip Historytrip_idAll trip details, route taken, fare breakdown

Geospatial Indexing with H3: Uber created the H3 library for hexagonal hierarchical geospatial indexing. Hexagons tile the Earth's surface uniformly (unlike rectangular grid cells), and each hexagon has 6 equidistant neighbors. This makes proximity searches efficient: find all drivers in the target cell and its 6 neighbors (7 lookups total, regardless of geographic area).

Specific Back-of-the-Envelope Numbers

Traffic:

  • 20 million rides per day globally (Uber's reported number)
  • 5 million active drivers sending location updates every 4 seconds = 1.25 million location updates/second
  • Ride matching: 20M rides/day = ~230 ride requests/second average, peaking at 3-5x = ~1,000/second
Key components of Design Uber with roles and responsibilities
Key components of Design Uber

Storage:

  • Driver location updates: 1.25M/sec * 50 bytes = 62.5 MB/second = 5.4 TB/day of raw location data
  • Active driver locations (in-memory): 5M drivers * 100 bytes = 500 MB (fits in RAM easily)
  • Trip history: 20M trips/day * 2 KB = 40 GB/day = ~14 TB/year

Matching latency target:

  • Under 10 seconds from ride request to driver assignment
  • Under 3 seconds for the geospatial search component
  • Driver location must be under 4 seconds stale

Map/routing:

  • ETA calculation uses precomputed road graphs with real-time traffic overlays
  • Route calculation: Dijkstra or A* on road graph, under 100ms per route

Sources