Design Yelp or Nearby Friends — System Design Interview Practice
Design a location-based service to find nearby places or friends based on geographical location. Work through the requirements, architecture trade-offs, and an interactive design review.
Concepts and architecture decisions to consider
- location servicesConcept to explore
- geospatialConcept to explore
- searchConcept to explore
- mobileConcept to explore
- real timeConcept to explore
Interview prompt
Design a geo-discovery service that finds nearby places or opted-in friends, supports category/filter/ranking queries, and remains accurate and low-latency as locations and updates change.
- Define place and friend location freshness, consent/visibility, radius semantics, filters, ranking, pagination, and geospatial index updates.
- Use cells/geohashes or equivalent partitioning, expand search rings for sparse areas, and control hot urban cells and popular queries.
- Separate location writes and place ingestion from query serving; explain stale positions, privacy deletion, and cache invalidation.
- Cover abuse, spoofed locations, regional failure, observability, and a safe empty/stale-result mode.
Requirements and scale assumptions
- Update opted-in friend locations and place metadata, then query nearby results by radius, category, rating, availability, and distance.
- Support privacy controls, blocked users, location TTLs, pagination, ranking explanations, map clusters, and place edits.
- Make updates retry-safe, remove expired/deleted locations, rebuild indexes, and degrade to coarse or cached results during outages.
- Meet p95 nearby-query latency under 150ms and never expose a friend location beyond its consent freshness window.
- Scale to 100M places/users and dense-city query hotspots without a single hot key or unbounded synchronous work.
- Do not lose committed state; make retries and duplicate events safe.
- Degrade safely when downstream workers, caches, or external dependencies fail.
- 100M places/users and 1M location updates per second at peak
- Partition by the primary tenant, user, item, or geographic key and isolate hot partitions.
- Keep serving state bounded; retain raw events or durable records for replay and auditing.
- Peak scale: 100M places/users; 1M updates/s — Capacity assumption that drives partitioning and backpressure.
- Latency target: nearby p95 < 150ms; location TTL enforced — User-facing budget for the primary request or read path.
- Durable boundary: Committed before async — Place records and consented location updates are authoritative; geospatial indexes and caches are derived.
- Async boundary: At-least-once workers — Keep Geospatial indexing (Quadtree, Geohash), Separate read and write paths, Cache popular locations off the synchronous path.
Key entities
- LocationUpdateupdateId, subjectId, cell, accuracy, occurredAt, consentVersion, expiresAt
Expiring, consent-scoped location evidence for yelp or nearby friends.
- AudiencePolicypolicyId, subjectId, audience, precision, blockedIds, version
Versioned privacy and sharing policy.
- PlaceRecordplaceId, category, cell, attributes, ownerId, version
Versioned place metadata used by nearby discovery.
- NearbyQueryqueryId, requesterId, center, radius, filters, freshness
Auditable nearby query and freshness contract.
Data flow
- 1. Capture consent-scoped updatesThe yelp or nearby friends gateway validates consent, precision, retention, timestamp, accuracy, and rate limits.
- 2. Build an expiring geo projectionWorkers index coarse cells with policy version and expiry while precise history remains restricted.
- 3. Evaluate nearby queriesThe query service retrieves bounded candidates, applies blocks and audience policy, then ranks by distance, category, and freshness.
- 4. Deliver opt-in proximity effectsApproved location or place changes trigger deduplicated notifications without exposing unnecessary precision.
- 5. Purge, audit, and recoverExpiry and deletion workers remove raw, index, cache, and notification state and repair missed invalidations.
Deep dives and trade-offs
- Privacy before retrievalEvaluate requester, subject, audience, block, precision, consent, and expiry before returning any candidate. Use coarse cells or transformed coordinates for the index and keep precise history in a restricted store. Fail closed when policy version or freshness is unknown.
- Hot cells and stale presencePartition by geo cell and time, isolate dense venues, and bound candidate fan-out. Carry last-seen and expiry metadata so an old heartbeat is never treated as current. Coalesce safe updates while preserving consent and deletion semantics.
- Deletion and auditMake user deletion remove raw, index, cache, and notification state through an idempotent workflow. Keep a minimal policy audit trail without retaining unnecessary precise location. Measure denials, stale results, precision, invalidation lag, and unusual access.
- Precision versus privacyReturn the coarsest precision that satisfies the use case and make finer precision explicit and consented. A precise global index increases privacy risk and hot-key pressure.
- Push versus pull nearby resultsUse pull for authoritative nearby queries and push only for opt-in, policy-approved changes. Push-only sharing can leak state after consent or connectivity changes.
- History versus ephemeral presenceKeep presence ephemeral and retain history only for an explicit user benefit and retention policy. Unlimited location history increases breach and deletion burden without improving nearby reads.