Preview — Pro guide
You are seeing a portion of this guide. Sign in and upgrade to unlock the full article, quizzes, and interview answers.
Design Proximity Services (Yelp / Google Places)
System design deep-dive for a geo-search platform handling 200M+ monthly users, sub-100ms nearby business search across 50M+ geo-indexed points, geohash/S2/H3 indexing tradeoffs, read/write split at 100:1, sharding by geohash prefix, and ranking by distance, rating, and personalization signals.
Why Proximity Search Is Harder Than It Looks
Proximity services — Yelp, Google Places, Foursquare, Uber Eats nearby restaurants — look deceptively simple: the user wants businesses within 5 km, sorted by relevance. In practice, this is a computational geometry problem disguised as a database query, and the naive approach (store latitude/longitude, run WHERE distance(lat, lng, user_lat, user_lng) < 5000) breaks immediately at scale. Yelp serves 200M+ unique monthly visitors searching across 50M+ business listings with a p99 latency target of under 100ms for nearby searches. Running a full-table distance calculation on 50M rows on every query is O(N) and cannot hit that target at any reasonable cost — you need spatial indexing that reduces the candidate set from 50M to ~100–500 businesses before any distance math runs. The second non-obvious challenge is the read/write asymmetry: a business listing changes rarely (add, edit, hours update), but is read by thousands of searches per hour if it's popular. This asymmetry — roughly 100:1 read-to-write ratio — means your index can afford to be slightly stale as long as it's fast and consistent enough to serve real-time search. A new restaurant appearing in search results 30 seconds after the owner creates it is acceptable; a search timing out is not. The third challenge is the geographic distribution problem: Manhattan has 200,000+ businesses in 59 km²; rural Montana has fewer than 50 businesses in 1,000 km². Any index that partitions space uniformly will have wildly uneven bucket sizes, and a query in Times Square will hit a bucket with 50,000 businesses while a query in rural Iowa hits a bucket with 3. Your index must handle non-uniform density gracefully — either by adaptive partitioning or by accepting that some cells need post-filtering at varying cost.
What Interviewers Are Testing in This Problem
Senior candidates are expected to know that you cannot SELECT * WHERE distance < R on 50M rows and must propose a spatial index. Staff candidates are expected to name the specific indexing approach (geohash, quadtree, S2, H3), explain the tradeoffs between them, and identify the boundary problem that every geohash-based system must solve. The question often expands to ranking (don't just return nearby businesses — return the most relevant nearby ones), write propagation (how does a new business appear in search?), and caching strategy (which geo cells get cached and why). A candidate who can explain why Yelp uses Elasticsearch with geo_distance queries while Foursquare migrated to Google S2, and what drove each choice, is demonstrating genuine production knowledge.
Clarifying Questions to Ask First
Radius search or bounding box?
Radius (5 km circle around user) is the standard for Yelp/Google Places. Bounding box (rectangle around map viewport) is what you need for map pan/zoom UX. They use different indexing strategies — radius search benefits most from geohash prefix queries; bounding box is natural for quadtrees. Assume radius search unless told otherwise.
What categories of entities are being indexed?
Businesses only (Yelp), or also users (Tinder nearby), vehicles (Uber driver locations), or events (Eventbrite)? Businesses are mostly static (update hourly at most); driver locations update every 4 seconds. Static and dynamic location indexing have completely different architectures. Assume static business locations.
What is the search radius range?
Typical Yelp default is 1 mile (~1.6 km) with options up to 25 miles (~40 km). Google Maps defaults to ~5 km. The radius directly determines which geohash precision level to query and how many neighbor cells to include. Clarify whether the radius is configurable per request.
What ranking factors matter?
Pure distance, rating, review count, price tier, open-now status, personalization (prior visits, saved places), or paid boost (ads)? Each factor added to the ranking pipeline increases compute cost. Clarify which are hard filters vs soft ranking signals.
What is the expected scale?
Yelp: 200M monthly users, 50M businesses, ~10K search QPS peak. Google Places: 1B+ monthly users, 200M+ places. Uber driver locations: 5M drivers updating every 4 seconds = 1.25M location writes/sec. The scale determines whether Redis GEORADIUS works or you need a dedicated spatial index cluster.
Do businesses have real-time attribute updates?
Business hours, menu items, temporary closures (COVID, weather), and special hours change. Does search need to reflect these within seconds or is minutes-delayed acceptable? This determines whether you can pre-index derived attributes (open-now) or must compute them at query time.
Multi-region or single region?
A purely local deployment serves one metro. A global deployment must geo-route queries (a user in Tokyo should not hit a US search cluster). Data residency may also apply — EU user data in EU. Assume global with geo-routing.