# Design Uber Rider App: Location, Maps, and Real-Time ETA

Source: https://www.techinterview.org/post/3233474984/design-uber-rider-mobile-app/
Updated: 2026-07-26 · techinterview.org

"Design Uber" usually means the dispatcher backend. In a *mobile* [system design](/system-design-interview-guides/) 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 — display a coarse last-known position instantly, then refine as the GPS locks on, so the map never blocks on a precise first fix. Interviewers watch for how you handle the permission prompt and cold-start fix latency.

- Search destinations and book rides — back the search box with a places autocomplete API and debounce queries so you aren't firing a request per keystroke. The booking flow confirms pickup, destination, and a fare estimate before it hits the dispatch backend.

- Track driver location in real time after booking — the tracking channel only matters after a match, so open it then and tear it down at drop-off. Expect follow-ups on update frequency versus battery, and on what the map shows before the first driver position arrives.

- Handle the ride lifecycle: requested → matched → arriving → in-trip → completed — model this as an explicit state machine (see below) with the server as the source of truth; the client mirrors transitions and never advances its own state. A stale or skipped transition is the classic bug interviewers probe for.

- Pay via stored payment methods — keep raw card numbers off the device and hold a payment token from a PCI-compliant vault, charging at trip completion. A common probe is how you recover when a card is declined mid-trip or at the end.

## 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 — drop from best accuracy to a coarser mode when the user hasn't moved, since full-accuracy GPS is one of the biggest battery drains on the device. Motion detection or the OS activity API can trigger the downgrade automatically.

- Switch off background location once ride is over — background location is the most scrutinized permission in app review, so release it the moment the trip completes. Holding it after drop-off wastes battery and invites privacy flags.

- Coalesce server pushes — process in batches if multiple arrive in a short window. Render only the latest position and batch the rest instead of handling each one; this cuts main-thread wakeups and keeps interpolation smooth.

## 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.
