HomeBlog › Design Google Maps

Design Google Maps

A mapping service is one of the richest system design prompts. The full arc — requirements, map tiles, the road graph, routing at scale, geospatial indexing, ETA, and traffic.

"Design Google Maps" is one of the meatiest system design interview questions you can get. It bundles three distinct problems into one: serving a huge visual map, indexing the whole planet spatially, and computing the fastest route across a graph with hundreds of millions of edges. Interviewers love it because it forces you to make crisp scoping decisions instead of trying to boil the ocean.

Here is a complete google maps system design walkthrough with an architecture diagram, following the standard requirements → API → design → data → scale arc.

   [ Mobile / Web Client ]
            |
     +------+------+
     |             |
     v             v
 [ CDN ]      [ API Gateway / LB ]
 map tiles         |
 (blob store)      +----------------------------------+
                   |            |            |         |
                   v            v            v         v
             [ Tile svc ]  [ Geocode/  [ Routing   [ Traffic
                            Places svc]  engine ]    ingest ]
                   |            |            |         |
                   v            v            v         v
             [ Blob +     [ Geospatial [ Road graph  [ GPS ping
              quadtree ]    index: S2/  + contraction  stream ->
                            geohash DB]  hierarchies]  segment
                                         + ETA weights speeds ]
Mapping service architecture: CDN-served tiles, geocoding/places, a routing engine over a preprocessed road graph, and a traffic pipeline feeding segment weights

1. Clarify the requirements

Functional requirements

Non-functional requirements

Back-of-the-envelope scale: a global road network is on the order of hundreds of millions of nodes and edges. Tiles are the biggest data volume — the world pre-rendered across ~20 zoom levels is petabytes of static imagery. Since it is a design a mapping service problem, scope it down: focus on tiles, geospatial indexing, and routing, and mention that map data ingestion (satellite, Street View, edits) is a separate offline pipeline.

2. API design

Three read paths carry most traffic: fetch tiles, geocode a query, and compute a route.

GET /tiles/{z}/{x}/{y}.png
  -> 200 pre-rendered map image for that quadtree cell

GET /geocode?q=1600+Amphitheatre+Pkwy
  -> 200 { "lat": 37.4224, "lng": -122.0841, "placeId": "..." }

GET /route?from=lat,lng&to=lat,lng&mode=drive
  -> 200 { "polyline": "...", "distanceM": 14200,
           "etaSec": 1080, "steps": [ ... ] }

3. Map tiles and storage

You never ship the whole map to the client. Instead the map is pre-rendered into small square tiles (typically 256×256 px) at every zoom level, addressed by a quadtree: at zoom z the world is a 2z×2z grid, and each tile is identified by (z, x, y). Zooming in splits one tile into four children — that is the quadtree.

Tiles are static, immutable images, so they are the easy part: store them in blob storage (S3/GCS) and serve from a CDN. The client requests only the handful of tiles inside the current viewport, and the browser/app caches them. Vector tiles (drawing instructions rather than pixels) are a common refinement that lets the client re-style and rotate without re-fetching.

4. The road graph

Routing runs on a weighted directed graph. Intersections are nodes; road segments are edges. Each edge carries a weight — usually travel time, derived from length, speed limit, road class, turn restrictions, and live traffic. One-way streets and turn penalties are why the graph is directed.

This graph is enormous and mostly static, so it is built offline from raw map data and loaded into memory on the routing servers. The dynamic part is the weights, which traffic keeps updating.

5. Routing at scale

The naive answer is Dijkstra or A*. They are correct, but on a continent-scale graph a single query would explore millions of nodes — far too slow for interactive use. The real trick is precomputation.

Contraction hierarchies (CH) are the standard technique. In an offline phase you rank nodes by importance and "contract" them one by one, adding shortcut edges that preserve shortest-path distances. At query time a bidirectional search only ever moves "upward" through the hierarchy, touching a tiny fraction of the graph and returning routes in milliseconds. The trade-off: CH preprocessing is expensive and assumes fixed weights, which is awkward when traffic changes constantly.

Customizable route planning (CRP) addresses that by splitting preprocessing into a slow, rarely-run phase (partition the graph into cells) and a fast metric customization phase that recomputes only cell-boundary shortcuts when weights change. That is how live traffic can reshape routes without rebuilding everything.

Interview signal: saying "Dijkstra" alone is a red flag at scale. The strong answer is "model it as a weighted graph, then precompute — contraction hierarchies for static weights, CRP-style customization when traffic must update the weights cheaply."

6. Geospatial indexing

A geospatial index maps 2D coordinates onto a 1D sortable key so that points near each other in the world stay near each other in the key space. That single idea powers snap-to-road, "restaurants near me," and sharding the map by region. The common schemes:

SchemeIdeaUsed by
GeohashInterleave lat/lng bits into a base-32 string; shared prefix = nearbyRedis, Elasticsearch
QuadtreeRecursively split space into 4 cells; also how tiles are addressedTile pyramids, spatial DBs
S2Project the sphere onto a cube, use a Hilbert curve for cell IDsGoogle (S2)
H3Hexagonal grid; uniform neighbor distancesUber (H3)

For a nearest-place query you compute the cell ID of the user, then scan that cell and its neighbors instead of the whole planet. To snap a GPS point to a road, you index road segments spatially and query the local cell for candidates.

7. ETA and traffic

ETA is not a separate system — it is the routing weight. The travel time of a route is the sum of the current time-weights on its segments. The interesting part is keeping those weights fresh:

The traffic pipeline is a classic stream-processing job: ingest pings, map-match them to segments, aggregate, and publish updated weights.

Key trade-offs the interviewer probes

Framework reminder: every system design answer follows the same arc — requirements → estimates → API → high-level design → data model → scale → trade-offs. Keep the system design cheat sheet in mind and narrate which stage you're in.

Structure any design answer with live AI support

CoPilot Interview surfaces a structured design skeleton — requirements, API, data model, and scaling — in about 4 seconds during real Zoom and Teams calls. Free for Windows and macOS, invisible on screen-share.

Download free

FAQ

How does Google Maps serve the map itself?

The map is pre-rendered into square image tiles at many zoom levels using a quadtree scheme. Tiles are static, so they are stored in blob storage and served from a CDN. The client only requests the handful of tiles visible in the current viewport.

How do you compute the fastest route at scale?

Model the road network as a weighted graph, then precompute shortcuts so queries are fast. Plain Dijkstra is too slow for continent-scale graphs, so production systems use contraction hierarchies or a similar precomputation that lets a query touch only a tiny fraction of the graph, returning routes in milliseconds.

What is geospatial indexing and why does it matter?

A geospatial index maps 2D coordinates to a 1D sortable key so nearby points cluster together. Geohash, Google's S2, Uber's H3, and quadtrees all do this. It powers snap-to-road, nearest-place lookups, and sharding the map by region.

How does Google Maps estimate ETA and use traffic?

Each road segment carries a travel-time weight. Live GPS pings from phones are aggregated to estimate current speed per segment, historical patterns fill gaps, and the routing engine sums segment times along the path. ETA is the routing weight, not a separate system.

How do you keep routing fresh as traffic changes?

Live conditions update segment weights continuously, but recomputing full contraction hierarchies is expensive. Systems use customizable route planning that separates a rarely-changing preprocessing phase from a cheap per-query metric update, so traffic changes apply without a full rebuild.