MSD0061 Nearby Place Recommendation

Design a nearby place recommendation system for Meta. When a user opens Facebook or Instagram on their phone, the app can recommend nearby places (restaurants, stores, parks, events) that the user might be interested in right now. Unlike a general recommendation system, the user’s location is constantly changing as they move, and the recommendation must reflect their current or predicted position, not where they were 10 minutes ago.

The system must retrieve candidate places using geohash or H3 spatial indexing, rank them by relevance (place popularity, user preferences, category match, distance, time of day), and serve results in under 200 milliseconds on a mobile device. It must handle cold start for new places with no visit history, handle users who just moved to a new city, and avoid recommending places that are permanently closed or temporarily unavailable. The recommendation must also account for context: a user looking for lunch at noon on a weekday has a different intent than the same user looking for dinner at 8 PM on a Saturday.

How would you design this system? Cover the geospatial retrieval architecture (geohash vs H3 vs quadtree), the ranking model that combines location distance with personalization features, how you handle real-time position updates and predict future position, how you handle cold start for new places and new users, and how you evaluate recommendation quality when the right recommendation depends on unobserved user intent.

Line-art scene: a person walking along a dashed path with future position markers, surrounded by nearby place labels such as ramen bar, coffee shop, city park and live music, with a question mark above the walker and latency and drift annotations

The Problem: the user keeps moving, hundreds of places sit within a few blocks, and the intent behind the app open (lunch, coffee, a park) is never observed, yet the first card has to appear in under 200 ms.

Answer

The design is a two-stage geo-recommender. Retrieval pulls a few thousand candidates from an H3 resolution-9 index using a k-ring around the user’s predicted position, an availability gate drops anything closed, and a multi-task ranker scores tap, save, and visit probability from user, place, distance, and context features. Two decisions carry the design. First, retrieval keys on H3 cells rather than geohash strings, because a k-ring is a genuine radius while geohash neighbors sit at uneven distances and cells stretch with latitude. Second, the top few hundred scored candidates are cached on the device and re-ranked locally as the user moves, so walking a block costs a local re-sort instead of a network round trip. Context enters as features rather than as a separate model: hour-of-week crossed with category affinity, and travel time instead of raw haversine distance, because people walk 200 metres for coffee and drive 5 km for dinner.

(1) H3 K-Ring Retrieval: places are indexed by resolution-9 cell, and a query fetches the k=2 ring (19 cells, about 2 square km) with k widened automatically in sparse areas until a candidate floor is met.
(2) Predicted Position, Not Last Fix: the query center is the last GPS fix advanced by velocity times expected staleness, with the cell resolution chosen by detected travel mode.
(3) Prefetch Plus On-Device Re-Rank: the server returns roughly 200 scored candidates with their coordinates; the device re-sorts by exact distance every few seconds, which also keeps precise GPS off the server.
(4) Availability Gate Before Ranking: permanent closures, current hours, and temporary-closure signals are applied as a hard filter in retrieval, never as a soft ranking penalty.
(5) Cold Start Priors With Bounded Exploration: new places inherit a prior from category, chain, and cell-level popularity, and reserve one exploration slot per result page with impression-capped bandit selection.

Pipeline diagram: device request feeds a position service that snaps to an H3 cell, then candidate retrieval, availability filter, and ranker; results go to top 10 cards with an on-device re-rank cache, and logs flow back through a feature store to nightly training

Figure 1: Serving path along the top row, offline loop along the bottom: one cheap spatial fetch, a hard availability gate, one scoring pass, and a cached candidate set the device can re-rank without another round trip.

Clarify Before Designing:
(1) Surface And Cadence: is this a dedicated Nearby tab the user pulls open, or an inline unit rendered on every feed load, and does it refresh continuously as the user walks?
(2) Location Permission: do we have precise foreground location and consent, or only coarse city-level location for most users, and is background position allowed?
(3) Inventory Quality: how complete are hours, category, and closure signals in the Places graph, and how stale is the worst market?
(4) Objective: are we optimizing discovery engagement, confirmed real-world visits, or downstream ad and business-page value, and which one settles ties?
(5) Geography And Scale: global coverage including sparse rural cells, or top metros first, and what peak QPS should the retrieval tier absorb?
(6) Cost Asymmetry: how much worse is recommending a closed restaurant than missing a good open one, since that ratio sets the availability gate’s aggressiveness?


Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *