“Design Uber” usually means the dispatcher backend. In a mobile system design round you are designing the rider experience: a live map, real-time driver tracking, a state machine that handles the entire ride lifecycle, and battery-friendly location updates.
Functional requirements
- Show current location on a map
- Search destinations and book rides
- Track driver location in real time after booking
- Handle the ride lifecycle: requested → matched → arriving → in-trip → completed
- Pay via stored payment methods
Architecture
Three core modules: location, map, ride state. They communicate via a state store (Redux-style on iOS, ViewModel/StateFlow on Android).
Location
iOS: CLLocationManager with desiredAccuracy = kCLLocationAccuracyBest while in active use. requestAlwaysAuthorization only when needed. Background updates are battery-expensive; we keep them off until the user has booked a ride and is waiting outside.
Android: FusedLocationProviderClient with high-accuracy mode. Foreground service required when tracking continues during ride.
Updates published to a local stream every 1–5 seconds depending on ride state. Throttle aggressively when stationary.
Map rendering
MapKit (iOS) or Mapbox/Google Maps SDK (cross-platform). Tiles are cached on disk. Driver position is rendered as a custom annotation; we interpolate between server-pushed positions for smooth motion (the server sends discrete points every 4–8 seconds).
Driver tracking
WebSocket or SSE channel from the server pushes driver location updates. We interpolate using CADisplayLink to render at 60fps even when updates arrive at 4 Hz.
Ride state machine
Finite state machine with explicit transitions. States: idle, requesting, matched, arriving, arrived, in_trip, completed, cancelled. Each state has its own UI and allowed actions. Server is authoritative; client mirrors state via push updates.
Offline behavior
If the user loses network mid-ride, the client shows the last-known driver position and a “reconnecting…” banner. Critical actions (cancel, contact driver) queue and retry.
Battery
- Cut location accuracy when stationary
- Switch off background location once ride is over
- Coalesce server pushes — process in batches if multiple arrive in a short window
Frequently Asked Questions
How is ETA computed?
Server-side using a routing engine that knows traffic, road segments, and historical timing. The client just displays the value and updates it on every server push.
How do you handle GPS jitter in cities?
Map-matching: snap user position to the nearest road segment. Smooth driver position with a Kalman filter or simple low-pass filter on incoming positions.
What happens when the user starts a ride and the app crashes?
On relaunch, fetch the active-ride state from the server and resume. The ride is server-owned; the client is just a viewport.