Design problems
Maps, mobility & logisticsHardSDE-3 40 min

Design maps navigation and ETA (Google Maps)

Asked at
DelhiveryGoogleOlaSwiggyUberZomato

The interviewer asks

“Design a maps and navigation service like Google Maps: users see the map, search a destination, get the fastest route with an accurate ETA that reflects live traffic, and get turn-by-turn navigation with rerouting.”

What a strong answer looks like

A strong answer splits the system into four parts. Map serving: vector tiles pre-generated per zoom level and served from a CDN, so most map views never reach the back end. Routing: the road network as a weighted directed graph, too big for plain Dijkstra per request, so you preprocess it with a speed-up technique such as Contraction Hierarchies or Customizable Route Planning (CRP), which answer queries in milliseconds and, in CRP's case, can absorb new traffic weights every minute. Traffic: GPS probes from phones are map-matched to road segments and aggregated into live speeds per segment, blended with historical speeds by time of week. ETA: the route's sum of segment times, corrected by an ML model trained on actual trip times. Navigation runs mostly on the device, with the server sending the route and live updates and rerouting when the user leaves the route or traffic changes. The deep dives are routing at scale, the traffic pipeline, ETA accuracy, and tiles.

Concepts to mention

Road network as a weighted directed graphPreprocessing speed-ups: Contraction Hierarchies or CRPMetric customisation for live trafficHMM map-matching of GPS probesLive plus historical (time-of-week) segment speedsML correction of the base ETAVector tiles by zoom level served from CDNOn-device navigation and off-route detectionProbe privacy: anonymisation and trimming

1 Requirements

Functional

  • Render the map at any zoom level with roads, labels and points of interest, in local languages where available
  • Compute the fastest route between two points for car, two-wheeler and walking, with 2-3 alternatives
  • Show an ETA that accounts for live traffic and typical traffic at the departure time
  • Turn-by-turn navigation with voice prompts; detect when the user leaves the route and reroute
  • Show live traffic colours on roads
  • Accept incident reports (accident, closure) and apply them to routing

Non-functional

  • Route computation p99 under 300 ms for city-scale trips, under 1 s for long cross-country routes
  • ETA accuracy: for most trips within ~10% of the actual time
  • Live traffic reflected in routing within ~1-2 minutes
  • Scale: ~50M daily users, ~10k route requests/s peak, ~1M GPS probe points/s
  • Map tiles served at > 99% CDN hit rate with < 100 ms load on 4G
  • Navigation keeps working through short network loss (route and tiles cached on device)

Out of scope (say it out loud)

  • Collecting and editing the base map data (survey cars, satellite imagery processing)
  • Place search and autocomplete in depth (mention as a separate service)
  • Public transit routing
  • Street View imagery

2 Estimates

Route requests~3k/s average, ~10k/s peak50M DAU × ~5 route requests/day (including reroutes and ride/delivery apps) ≈ 250M/day ≈ 2.9k/s; evening peak ~3x
GPS probes~1M points/s~5M devices actively navigating or tracked at peak (including drivers of partner apps) × 1 point/s, sent in batches every 5-15 s
Road graph (India)~50-100M nodes, ~100-200M directed edgesOrder of magnitude for a country-scale OSM-like graph; ~50 bytes per edge with attributes ≈ 5-10 GB in memory
Traffic segments~20M segments with live speedsOnly roads that carry probes regularly; updated every minute → ~330k segment updates/s at most, usually far fewer change
Historical speed profiles~50-100 GB20M segments × 168 hours of the week × ~2-4 bytes per speed ≈ 7-13 GB per profile set; several profiles (weekday/holiday, vehicle type)
Tiles~100s of millions of tiles, a few TBVector tiles for zoom 0-16 over India; most storage is at high zoom; only a small fraction are hot
Tile requests~500k/s at peak, mostly CDN~5M active map sessions × ~1 tile request per 10 s while panning or moving

3 API

EndpointWhat it does
GET/tiles/{style}/{z}/{x}/{y}.mvtVector tile for a zoom level and tile coordinate; cache headers for CDN and device
POST/v1/routesorigin, destination, waypoints, mode, depart_at, avoid (tolls, highways) → up to 3 routes with polyline, steps, distance, ETA, traffic per section
POST/v1/eta-matrixMany origins × many destinations → travel times; used by ride-hailing and delivery dispatch
POST/v1/probesBatch of GPS points (anonymised session id, lat, lng, speed, heading, accuracy, ts)
GET/v1/traffic/{z}/{x}/{y}Traffic overlay tile with segment speed classes; refreshed every 1-2 minutes
POST/v1/navigation/{session_id}/rerouteCurrent position and heading → new route when off-route or a faster route exists
POST/v1/incidentsUser or partner reports an accident or closure; verified then applied to routing weights

4 Data model

road_graphBuilt offline, stored in S3, loaded into memory on routing servers
nodes (id, lat, lng)edges (from, to, length, road class, speed limit, turn restrictions, toll, access by vehicle type)

Rebuilt from map data periodically (daily or weekly); versioned so all routing servers use the same graph.

routing_preprocessingS3 artefacts, memory-mapped on routing servers
partition cellsboundary nodesshortcut edges / overlay graphs per level

Metric-independent part rebuilt with the graph (hours); metric customisation with traffic weights rebuilt every minute (seconds).

live_segment_speedsRedis / in-memory store, published as versioned snapshots
segment_id → speedconfidencesample_countupdated_at

Produced by the traffic pipeline every minute; routing servers pull snapshots.

historical_speedsColumnar files in S3, loaded to memory
segment_idtime-of-week bucket (15 min)median speedpercentiles

Used when live data is sparse and for future departure times.

probes_rawKafka → S3 (short retention, anonymised)
session_id (rotating)latlngspeedheadingaccuracyts

Privacy: rotating ids, trimmed trip start and end points, short retention.

trip_outcomesS3 / data warehouse
route_idpredicted_etaactual_durationroute featuresdeparture time

Training data for the ETA correction model.

tilesS3 + CDN
key = style/z/x/y → compressed vector tile

Pre-rendered for low zooms; high zooms generated on demand and cached.

5 Architecture

CLIENTSEDGESERVICESASYNCDATAEXTERNALvector tilescache missroute, rerouteETA matrixcorrect ETAweights snapshotGPS batchessegment speeds/minhistory, outcomesmap updatesgraph + tilesload graphRide / delivery appsMaps app (nav engine)API gatewayCDN (tiles)Routing service (CRP)Probe ingestETA model serviceKafka (probes)Map-matching + trafficGraph & tile buildersLive speeds storeS3 (graph, tiles,history)Map data sources
ClientEdge / gatewayService / workerQueue / streamCacheDatabase / storageAI / modelThird partyrequestasync (event / queue)

Hover a box to highlight its connections.

6 Request flows

Get a route with ETA

  1. 1User searches 'Kempegowda Airport' (place search is a separate service returning coordinates) and taps Directions for car.
  2. 2Gateway routes the request to a routing server; the request is stateless, so any replica with the current graph works.
  3. 3The server snaps origin and destination to the nearest road edges, considering heading and which side of the road.
  4. 4It runs a bidirectional query on the CRP overlay graph using the current traffic-customised weights: a few milliseconds of search instead of exploring millions of nodes.
  5. 5It finds 2-3 alternatives (routes that share less than ~70% of their length and are not much slower) and unpacks shortcuts back to real road segments.
  6. 6For each route, the base ETA is the sum of segment times (live speeds near now, historical speeds for later parts of the trip) plus turn and signal penalties.
  7. 7The ETA model service corrects the base ETA using features like route type, time of day, weather and recent prediction errors on similar routes.
  8. 8The response returns polylines, turn-by-turn steps, ETAs and traffic per section; the app caches tiles along the route for offline use.

Live traffic update

  1. 1Phones in navigation send GPS points in batches every few seconds to probe ingest, which validates, anonymises and writes to Kafka partitioned by region.
  2. 2Map-matching workers use a hidden Markov model (HMM) to snap each noisy trace to the most likely sequence of road segments.
  3. 3They compute per-segment travel times and aggregate per segment per minute with outlier removal (a bus stop or a parked rider is not traffic).
  4. 4Segments with enough samples get a live speed; sparse ones blend toward the historical speed for that time of week, with a confidence value.
  5. 5Every minute a new speed snapshot is published; routing servers run metric customisation to update the overlay weights in seconds.
  6. 6Navigating clients periodically ask 'is there a faster route?'; if the new ETA saves more than a threshold, the app offers a reroute.

7 Deep dives

Routing at scale: why not plain Dijkstra

Dijkstra on a country graph with ~100M nodes explores millions of nodes for a long route, taking seconds of CPU per request: impossible at 10k requests/s. A* with a straight-line heuristic helps a little but not enough on road networks. The answer is preprocessing. Contraction Hierarchies (CH) rank nodes by importance and add 'shortcut' edges that skip unimportant nodes; queries then only go 'upward' in importance from both ends and meet in the middle, exploring a few hundred nodes and answering in about a millisecond. The weakness: CH preprocessing for one set of weights takes minutes or more, so live traffic is awkward. Customizable Route Planning (CRP), used in Bing Maps, splits preprocessing into two parts. A slow, metric-independent part partitions the graph into nested cells and finds boundary nodes. A fast customisation step recomputes the shortcut costs between boundary nodes for new weights in seconds, in parallel per cell. That makes it a good fit for traffic updated every minute and for different vehicle types (two-wheelers, cars, trucks with restrictions). Queries run bidirectionally over the overlay levels and take milliseconds. Shard routing servers by region with overlapping borders, or replicate the whole country graph per server, since it fits in memory.

Traffic from GPS probes

Live traffic is crowdsourced from phones. Raw GPS points are noisy (5-30 m error, worse between tall buildings), so the first step is map-matching: given a sequence of points, find the most likely path on the road graph. An HMM does this well: candidate road segments near each point are hidden states, emission probability decreases with distance from the point, and transition probability prefers paths whose road distance is close to the straight-line distance between points. Viterbi finds the best path. From matched traces, compute travel time per segment, then aggregate per segment per minute. Clean the data: remove stationary points (a parked car or a delivery rider waiting), separate two-wheelers from cars because two-wheelers move through jams faster in Indian traffic, and use medians, not means. Low-traffic roads have few probes, so blend live estimates with historical speeds weighted by sample count. Privacy matters: rotate session ids, cut off the first and last few hundred metres of each trip, aggregate before storing, and delete raw probes quickly. This pipeline runs in Flink or a similar stream processor, partitioned by geographic region so each worker owns a set of segments.

Making the ETA accurate

Summing segment speeds gives a base ETA, but it is biased in known ways. Live speeds describe now, but you will reach a segment 40 minutes from now, so use a time-dependent model: live speed for the first part of the route, blending into the historical profile for the departure-time-plus-offset later. Add turn costs (right turns across traffic in India, U-turns), signal delays and speed limits. Then correct with machine learning: train a model on millions of completed trips (predicted vs actual), with features like route length, road classes, time of day, day of week, weather, events and region. Google Maps and DeepMind described using graph neural networks over 'supersegments' to improve ETA accuracy; gradient-boosted trees on route features are a strong simpler start. Measure accuracy with percentage error, and look at the tail (trips where the ETA was off by more than 20%), not only the average. Also show uncertainty: for long or uncertain routes, a range ('45-60 min') is more honest. Keep updating during navigation: the ETA is recomputed from the current position with fresh traffic, and large changes are explained ('heavy traffic ahead').

Tiles and on-device navigation

Map rendering must not hit the back end for every pan. The world is divided into tiles by zoom level (z) and coordinates (x, y), with 4^z tiles at zoom z. Vector tiles (Mapbox Vector Tile format) carry geometry and labels, and the phone renders them, so one tile serves any screen density, rotation and language, and is far smaller than images. Tiles for low zooms and busy areas are pre-generated; higher zooms are generated on demand from the map database and cached in S3 and the CDN with long TTLs and versioned URLs, so a map update just changes the version. Traffic colours are a separate, short-TTL overlay layer so base tiles stay cacheable. Navigation runs mostly on the device: the app has the route, the tiles along it and the steps, tracks position with GPS and sensors, announces turns, and detects 'off route' (position far from the route for several consecutive fixes). Only then, or for periodic traffic checks, does it call the server for a reroute. Offline maps download a region's tiles and a compact routing graph, which matters in India where highway connectivity drops.

8 Trade-offs

Contraction Hierarchies vs CRP

CH gives the fastest queries and is simple to implement with open-source tools (OSRM uses it), but changing weights means slow re-preprocessing. CRP queries are slightly slower but traffic customisation takes seconds. With live traffic as a requirement, CRP (or a CH variant that supports customisation) is the better fit.

Server-side navigation vs on-device

Server-driven navigation is easier to update but fails when the network drops and costs round trips. On-device navigation with server-provided routes and periodic traffic checks is resilient and fast. The cost is a bigger app and logic split between client and server.

Vector tiles vs raster tiles

Raster images are simple and render the same everywhere but are large and fixed in style and language. Vector tiles are small, styleable and rotatable, but need rendering work on the device. Modern apps use vector tiles, keeping raster only for satellite imagery.

9 Bottlenecks

ETA matrix requests from partners

Ride-hailing and delivery dispatch ask for many-to-many ETA matrices (for example 50 drivers × 20 orders) constantly. At 10x, these dominate CPU. Use one-to-many algorithms that reuse the search (like PHAST or bucket-based CH queries), cache cell-to-cell travel times for a minute, and give partners a separate, rate-limited cluster.

Probe ingestion spikes

During evening rush, probes peak with traffic. Kafka absorbs bursts; map-matching scales by region partition. If workers fall behind, drop probes on roads that already have enough samples (sampling) rather than letting all traffic data lag.

10 Failure handling

Traffic pipeline down

Routing servers keep the last weights; after a few minutes they fall back to historical speeds for the current time of week. ETAs get less accurate but routes still work. Alerting tracks snapshot age.

Bad graph build (missing bridge)

A broken map update can make routes take huge detours. Validate every new graph with thousands of known benchmark routes before rollout, roll out by region gradually, and keep the previous version to roll back.

User loses network during navigation

The app continues with the cached route and tiles and keeps giving turn instructions. Rerouting works on-device with an offline graph if downloaded; otherwise it retries when the network returns.

11 What impresses

  • Explaining why Dijkstra does not scale and how CH or CRP fix it, and why CRP suits live traffic
  • Describing map-matching with an HMM and data cleaning like separating two-wheelers
  • Using time-dependent ETA: live speeds now, historical speeds for later segments
  • Separating base tiles (long cache) from traffic overlay (short TTL)
  • Validating graph builds against benchmark routes before rollout
  • Mentioning probe privacy measures

12 Mistakes

  • Running Dijkstra on the full graph per request
  • Using straight-line distance for ETA
  • Treating raw GPS points as exact positions on roads
  • Serving every map view from origin servers instead of tiles on a CDN
  • Ignoring how traffic data is collected
  • Making navigation fully dependent on the network

13 Follow-ups

Q1How would you add truck routing with height and weight limits?
Q2How do you detect a new road or a closed road from probe data?
Q3How would you serve ETA matrices for a food delivery company at 50k requests/s?
Q4How would you show ETA ranges instead of a single number?
Q5How do you support routing in two-wheeler-heavy Indian traffic?
Q6How would you add EV routing with charging stops?

Saved on this device. Create a free account to keep it on every device.

Practise this with Sam

A real mock interview, out loud, with an honest scorecard. Free to start.

Start free