System Design Space
Knowledge graphSettings

Updated: April 10, 2026 at 5:55 PM

Google Maps / Proximity Service - geosearch

medium

A classic map geosearch case: nearby lookup, spatial indexing, regional caching, ranking, and a tight latency budget.

Geosearch does not get hard because of the distance formula. It gets hard when the user keeps moving the map while the densest areas create the sharpest traffic spikes.

The chapter ties together geocells, regional caching, index preparation, request serving, and POI updates into one working architecture where both freshness and update cost matter.

For interviews and architecture discussions, this case is useful because it forces you to explain radius search, hot-zone handling, and where the boundary sits between response speed and result precision.

Geo Cells

The key choice is how to cover a search radius with neighboring cells without exploding the amount of unnecessary lookup work.

Hot Zones

City centers, airports, and stations create local peaks, so caching and partitioning should be designed for skew rather than average traffic.

POI Freshness

Place status, opening hours, and temporary restrictions go stale faster than the geometry itself, which is why metadata updates cannot wait for rare batch jobs.

Regional Cache

Caching close to the user reduces latency, but it has to line up with geographic partitioning and clear degraded modes.

Source

System Design Interview

A classic walkthrough of Proximity Service as a core geosearch pattern in product systems.

Open review

Proximity Service answers a simple question: what is nearby for a given point, radius, and set of filters. At scale, the difficulty is less about distance math itself and more about spatial indexing, viewport-driven access patterns, and hotspot behavior in the busiest areas.

Even when places do not move every second, the index still sees write amplification from incremental updates, recut cell coverage, and regional synchronization. That is why large deployments usually rely on geographic partitioning first, then apply ordinary sharding inside each region.

Requirements

On the surface this looks like a simple nearby lookup, but internally it is an interactive radius search with a very tight latency budget. In major cities, a handful of districts can climb into millions of QPS, so the design has to preserve both UI responsiveness and load skew tolerance.

Functional

  • As the user moves the map, the system returns the nearest POIs in the current viewport.
  • It supports nearby lookup by radius, category, and text query.
  • Pagination and result ordering remain stable while the user pans and zooms the map.
  • Autocomplete is separated from the API that returns full place details.
  • Point status, availability, and temporary restrictions can be updated near real time.

Non-functional

Latency: p95 < 200ms

The map UI should stay responsive during pan/zoom and repeated nearby requests.

Availability: 99.99%

Search should keep working even when part of the index or cache is degraded.

Freshness: minutes, not hours

New, closed, or temporarily unavailable places should reach the results quickly.

Scale: millions of QPS

Geo-distributed traffic arrives with strong regional and time-of-day skew.

High-level architecture

The request path should stay clearly separated from index preparation. Nearby lookup lives on a short user-facing read path, so the serving layer needs an explicit degraded mode whenever cache coverage is weak or the search radius suddenly expands.

Client applications

Map UI, pan/zoom, and nearby lookup

Geo gateway

Authentication, quotas, and regional routing

Serving layer

Index access, filtering, and ranking

Hot cache

Redis/Memcached for popular geocells and categories

Geo index store

S2/H3/Geohash plus category posting lists

POI metadata database

Name, opening hours, rating, and business tags

The request runs in two phases: first candidate retrieval across neighboring cells, then ranking based on distance, relevance, and business signals.

Interactive walkthrough of a nearby request

Change the category and radius, then step through the request path.

Example coordinates: 37.7793, -122.4192

Step 1 of 5

Geo gateway: request validation and normalization

The edge service validates the query and sends it to the nearest serving region.

Latency budget: 15-25ms
  • Checks the API key, quotas, and required parameters.
  • Normalizes lat/lng, radius, and client locale.
  • Routes the request into the closest proximity region.
{
  "lat": 37.7793,
  "lng": -122.4192,
  "radius_m": 1500,
  "category": "cafe",
  "region": "us-west-1",
  "auth": "ok",
  "quota": "ok"
}

Choosing a spatial index

There is no universally best structure here. In practice this is an engineering trade-off between cover accuracy, update cost, and the amount of geometric complexity you are willing to carry at scale.

ApproachWhere it helps mostTrade-offs
GeohashA quick start and storage in a simple key-value layerCell geometry is less uniform, and border artifacts show up more often.
S2Global maps and clean spherical geometryIt requires a more careful implementation and is harder to debug.
H3Density analytics, heatmaps, and region-based aggregationMoving between resolutions needs careful tuning.
R-tree/QuadTreeHeavy spatial queries directly inside the databaseUpdates are more expensive, especially under higher write load.

API and data model

Main API

GET /v1/places/nearby?lat=37.78&lng=-122.41&radius=1500&category=cafe&limit=20

Response:
{
  "items": [
    { "place_id": "p123", "distance_m": 120, "score": 0.91 },
    { "place_id": "p889", "distance_m": 240, "score": 0.88 }
  ],
  "next_page_token": "..."
}

Index and metadata

  • geo_cell_index: cell_id -> place_ids
  • poi: place_id, name, category, coords, rating, business_hours
  • popularity_signals: recent clicks/check-ins/reviews
  • change_log: events used for incremental reindexing

Reliability and common mistakes

The tricky part of this case is holding together locality, acceptable freshness, and a clear degraded mode when part of the geo index or cache becomes temporarily unavailable.

What helps in production

  • Regional partitioning by cell ranges plus replication across zones.
  • A two-level cache: edge coverage for hot areas and a service cache inside each region.
  • Graceful fallback to a coarser index resolution instead of a full outage.
  • Incremental reindexing instead of rebuilding the entire dataset every time.

Common mistakes

  • Looking in only one cell and forgetting about neighboring cells at the radius boundary.
  • Sorting only by distance and ignoring rating, relevance, or place status.
  • Mixing the online serving path with the batch path that prepares the index and metadata.
  • Building one global cache without regional partitioning or stampede protection.
  • Failing to deduplicate POIs when multiple data providers feed the same area.

Tool

S2 Geometry

A practical toolkit for cell-based spatial indexing on the surface of a sphere.

Open site

Related chapters

Enable tracking in Settings