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