CASE STUDY

Interactive Map with 100 Million+ Points

3 min read·577 words·Advanced

Asked at

1 candidate report in Apr 2026

How to use this case study

SDE-2 / Mid

Explain why you can't send 100M points to a browser, and how zoom-dependent aggregation (heat maps or clusters when zoomed out, pins when zoomed in) solves it.

SDE-3 / Senior

Go deeper on map tiles (z/x/y), a precomputed tile pyramid, vector tiles, and CDN caching.

Staff / Principal

Discuss updates to the data, filters that change which points show, dynamic vs precomputed tiles, and client rendering limits (WebGL).


0) Problem Restatement

Google asked: design an interactive map that shows more than 100 million data points (e.g., every store, sensor or event location). At zoomed-out levels, show aggregated information (a heat map or cluster bubbles with counts). At close zoom, show individual pins that can be clicked. Panning and zooming must be smooth.


1) Why It's Hard

  • 100M points × ~20 bytes ≈ 2 GB of raw coordinates. A browser can't download or draw that.
  • On screen, only a few thousand things can be shown usefully anyway.
So the rule is: never send more to the client than what can be seen, and pre-summarize the far-away views.


2) Map Tiles (the core idea)

  • The world map is split into tiles by zoom level z: zoom 0 = 1 tile for the whole world, zoom 1 = 4 tiles, zoom z = 4^z tiles. Each tile is addressed as z/x/y.
  • The client asks only for tiles covering the current screen at the current zoom (typically 10–30 tiles).
  • For each tile, we precompute what to show:
  • Low zoom (0–8): aggregated heat map values or cluster counts per grid cell inside the tile.
  • Mid zoom: clusters (e.g., "1,240 here").
  • High zoom (14+): individual points in that small area (a few hundred per tile at most).

Architecture Diagram

flowchart LR
    SRC[("100M points - DB / data lake")] --> TB["Tile builder - batch, per zoom"]
    TB --> TP[("Tile pyramid - vector tiles z/x/y")]
    TP --> CDN["CDN"]
    CDN --> CL["Browser - WebGL map"]
    CL -->|"click a pin"| API["Point details API"]
    API --> SRC
    UPD["Point updates"] --> DIRTY["Mark affected tiles dirty"]
    DIRTY --> TB

3) Building the Tile Pyramid

  • A batch job (e.g., Spark, or tools like tippecanoe) assigns each point to its tile at the highest zoom, then rolls up counts to parent tiles zoom by zoom (each parent = the sum of its 4 children). This is cheap once the highest level is done.
  • Store tiles as vector tiles (compact binary with points or cells and attributes), so the client can style them and show tooltips.
  • Total tiles: only tiles with data are stored. Empty ocean tiles are skipped.
  • Serve from object storage through a CDN. Tiles are static files, so they're very cacheable and cheap.


4) Client Rendering

  • Use a WebGL map library (e.g., Mapbox GL / deck.gl) that can draw tens of thousands of shapes smoothly.
  • As the user zooms, fetch the new zoom's tiles and fade between levels. Prefetch the neighboring tiles.
  • Clicking a pin calls a details API by point ID (the tile only carries IDs and minimal attributes).


5) Updates and Filters

  • Data changes: mark the tiles containing changed points as dirty (at all zoom levels up the chain) and rebuild them incrementally, with cache-busting via tile versions.
  • Filters (e.g., "only category = restaurant"): options are:
  • Precompute separate pyramids for a few common filters.
  • Store per-category counts in each aggregated cell, and let the client combine selected categories.
  • For arbitrary filters, generate tiles dynamically from a spatially indexed database (PostGIS with ST_AsMVT, or ClickHouse with geohash cells), cached per filter.


6) Wrap-Up

Split the world into z/x/y tiles and precompute a tile pyramid: individual points at high zoom, and cluster or heat-map aggregates rolled up zoom by zoom at lower levels, stored as vector tiles and served through a CDN. The WebGL client fetches only visible tiles for the current zoom and loads point details on click. Rebuild dirty tiles incrementally on data changes, and handle filters with per-category counts, extra pyramids or cached dynamic tiles from a spatial database.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →