Nearby Friends

Live locations of friends within a radius

Design a feature that shows each user which of their friends are within a few miles right now, with locations that update live as everyone moves.

Overview

Users who turn the feature on share their location with their friends. Each user sees a list or map of the friends who are within a few miles, with the distance, and the entries move as people move. A friend who walks out of range disappears; one who walks in appears.

It sounds like the Proximity Service problem, but the data behaves the opposite way. Businesses rarely move and are searched often; here every point moves every 30 seconds, and nobody searches. Each user's set of interesting points is small and fixed (their friends), so the hard part is not a spatial index but fan-out: every update has to reach every online friend, and the system must decide quickly whether that friend is close enough to care. The tools are a WebSocket connection per user, a pub/sub channel per user that friends' servers subscribe to, and a distance filter on the receiving side.

Questions to ask first

  • How near is nearby? — 5 miles (about 8 km), one setting for everyone
  • How fresh must a location be? — Updated every 30 seconds while the app is in use
  • How many users? — 100 million have the feature on; 10 million share at peak
  • How many friends? — 200 on average; a product cap of 5,000
  • Who can see me? — Only friends, only if I opt in, minus anyone I hide from
  • Do we keep history? — Yes, for the user's own timeline and for analysis, with a retention limit
  • Strangers nearby too? — Not at first; asked as a follow-up

What you will be able to do

  • Trace one location update from a phone to the screens of the friends who are close enough.
  • Size the fan-out and explain why the pub/sub tier, not storage, is the bottleneck.
  • Write the distance filter, including late updates and friends who leave the radius.
  • Scale the pub/sub tier with consistent hashing and reshard it without losing users.
  • Deploy stateful WebSocket servers, protect privacy, and adapt the design to strangers nearby.

Key concepts

  • WebSocket servers
  • Location cache with TTL
  • Channel per user
  • Redis Pub/Sub
  • At-most-once delivery
  • Distance filter
  • Consistent hashing
  • Connection draining
  • Location precision
  • Geohash channels

Functional requirements

  • Turn location sharing on or off; it is off by default
  • See friends within 5 miles with their distance and when they were last updated
  • Receive updates live while the app is open
  • Hide your location from chosen friends, or share it only approximately
  • Keep a history of your own locations, with deletion

Non-functional requirements

  • A friend's move reaches the screen within a few seconds (a target we chose)
  • A missed update is acceptable; a wrong one shown to the wrong person is not
  • Locations older than 10 minutes are never shown as current
  • Hiding or turning sharing off takes effect within seconds
  • Deploys and server failures cause reconnects, not outages

Interview questions

  • Why a pub/sub channel per user instead of storing locations and querying friends?
  • Redis Pub/Sub loses messages. Why is that acceptable?
  • How do you scale the pub/sub tier, and what happens when you add a node?
  • How does a user who just opened the app see their friends immediately?
  • How do you deploy the WebSocket servers without disconnecting everyone?
  • What changes if users want to see random people nearby, not just friends?
  • Where is the bottleneck, and how did you find it?
  • How do you protect users' privacy?

Sign up free to read the full topic

More System Design topics

Start free on Cariara · Coding problems · System design studio