System design · must-tier · asked at Amazon, Apple, Google, Meta, Microsoft, Netflix

Design Nearby Places Search

hardhldgeospatialindexing

Prompt

"Design the backend for 'find places near me': given a location and a radius, return nearby businesses, ranked, fast enough for a map that redraws as the user pans."

Clarifying questions

  • How many places? On the order of 200 million business listings worldwide.
  • What is a query? A latitude, longitude, radius (or a viewport rectangle), optional category or text filter, and a result limit of around 20-50.
  • How often do places change? Listings are added and edited at a modest rate (thousands per second globally at most); their locations almost never change. Opening hours and ratings change more often than coordinates.
  • Do we track moving objects? No. Places are static. Live driver or friend location is a different problem.
  • Ranking? Distance is the primary factor but rating, popularity, and whether the place is open now matter too.
  • Latency? Under 100 ms at p99 for the search call, since the map issues a new query on every pan.
  • Read/write ratio? Overwhelmingly reads.
  • Consistency? A new listing can take minutes to become searchable; edits to hours or ratings can lag similarly.

Requirements

Functional

  • Search places within a radius or viewport, with optional filters, returning ranked results with distance.
  • Fetch details for a place.
  • Add and edit places (owner or moderation flow) with eventual visibility in search.

Non-functional

  • Low latency reads at high QPS; the index must be memory-resident.
  • Availability over freshness: serving slightly stale listings is fine, failing the search is not.
  • Global coverage with dense cities and empty oceans; the index must handle wildly uneven density.

Back-of-envelope

  • Users: assume 500M DAU of a maps product, each doing 5 nearby searches/day → 2.5B searches/day ≈ 29,000 QPS average; peak 3-5× → 100,000-150,000 QPS. Panning multiplies this, so debounce on the client and cache aggressively on the server.
  • Places: 200M. Core record for search (id, lat, lng, category ids, rating, popularity score, open-hours bitmap) ≈ 200 B → 40 GB. Full details (name, address, photos, reviews) ≈ 5 KB average → 1 TB, kept in a separate store and fetched by id.
  • Index: 200M entries × (cell id 8 B + place id 8 B) ≈ 3.2 GB plus overhead. The search index comfortably fits in memory on each of many replicas; replicate rather than shard, unless the enrichment data is co-located.
  • Writes: assume 10,000 place edits/s peak globally, most touching attributes rather than coordinates. Under 100 coordinate changes/s. Index updates are cheap relative to reads.
  • Response size: 30 results × 300 B ≈ 10 KB. At 150,000 QPS that is 1.5 GB/s outbound. Fine.
  • Cache: results keyed by (rounded location cell, radius bucket, filter set). Popular areas (city centres) dominate; a few million cache entries × 10 KB = tens of GB, spread across a cache tier. Hit rate for the head is high because many users near the same spot ask the same thing.

Last reviewed 8 September 2026