Practice/Roblox/Design a friend activity system for a gaming platform
Design a friend activity system for a gaming platform
System DesignMust
Problem Statement
Design a system that displays personalized messages showing which friends have played a specific game, such as "3 of your friends played this game recently" or "Alice and 2 others played this today." This feature helps drive game discovery through social proof -- when players see that their friends enjoy a game, they are more likely to try it themselves. Think of similar features on Steam ("5 friends play this game"), the PlayStation Store, or the Roblox game detail page.
The challenge is combining two expensive operations at scale: maintaining an up-to-date graph of who is friends with whom, and tracking game play activity across hundreds of millions of users in near real-time. A naive approach would query the friends list for every page view and then check each friend's recent activity, but this creates fan-out that scales linearly with friend count and becomes prohibitively expensive at millions of requests per second. The system must pre-compute or cache these social signals while keeping them fresh enough that a friend's game session from 10 minutes ago appears in the results.
Interviewers use this question to evaluate your understanding of social graph queries, activity feeds, denormalization strategies, and the trade-off between computation cost and data freshness in a read-heavy system.
Key Requirements
Functional
- Friend activity display -- for a given user viewing a game page, show how many of their friends have played that game recently and display names of up to 3 friends
- Recency window -- activity is considered "recent" within a configurable window (e.g., last 7 days), and older activity is excluded
- Activity tracking -- capture game play sessions as they happen, including start time, duration, and game identifier
- Privacy controls -- users can opt out of showing their activity to friends, and the system respects these settings in all queries
Non-Functional
- Scalability -- support 500 million users, average 200 friends per user, 50 million daily active players, and 100 million game page views per day
- Latency -- friend activity data returns within 100ms at p95 to avoid slowing down game page loads
- Freshness -- a friend's game session appears in the activity display within 15 minutes of starting
- Reliability -- the system degrades gracefully if activity data is temporarily unavailable; game pages still load, just without friend activity context
What Interviewers Focus On
Based on real interview experiences, these are the areas interviewers probe most deeply:
1. Data Access Pattern and Fan-Out Strategy
The core challenge is efficiently answering "which of my friends played game X recently?" for millions of concurrent users. Interviewers want to see how you avoid the naive approach of joining the friends graph with the activity log on every request.
Hints to consider:
- Consider fan-out on write: when a player starts a game session, push an activity entry to each of their friends' pre-computed activity caches
- Alternatively, use fan-out on read with aggressive caching: when a user views a game page, query their friend list, batch-check recent activity, and cache the result per user-game pair
- Evaluate a hybrid approach: fan-out on write for the activity stream, but compute the per-game friend count on read from a denormalized activity store
- Think about the asymmetry: most users have hundreds of friends (manageable fan-out), but some influencers have millions (need special handling)
2. Activity Ingestion and Storage
Game sessions generate a continuous stream of activity events. The system must ingest these at high throughput while making them queryable for the friend activity feature within minutes.
Hints to consider:
- Use Kafka to ingest game session events at high throughput, partitioned by user ID for ordered processing per player
- Store recent activity in a time-windowed data structure: Redis sorted sets (scored by timestamp) with TTL matching the recency window, or Cassandra with TTL columns
- Design the storage schema to support two access patterns: "all recent activity for user X" and "did user X play game Y recently?"
- Compact activity data: instead of storing every session, maintain a "last played" timestamp per user-game pair to minimize storage
3. Pre-Computation vs. On-Demand Querying
Whether to pre-compute friend activity per game or compute it on demand has major implications for cost, freshness, and complexity. Interviewers expect you to analyze both approaches.
Hints to consider:
- Pre-computation (materialized views per user-game pair) provides fast reads but is expensive to maintain: every activity event triggers updates for all friends across all games they might view
- On-demand querying is simpler but slower: fetch friend list, batch-check activity store, filter and aggregate -- requires careful caching to meet latency SLAs
- A pragmatic middle ground: pre-compute for the top 100 most popular games (where most page views occur) and compute on demand for long-tail games
- Cache on-demand results with a short TTL (5-10 minutes) to reduce repeated computation for popular game pages
4. Social Graph Integration and Privacy
The friend graph is a shared dependency that must be queried efficiently and respect privacy settings. Interviewers probe how you interact with an existing social graph service.
Hints to consider:
- Cache friend lists locally (per-server or in Redis) with a TTL of a few minutes, since friend relationships change infrequently compared to activity
- Batch friend list lookups: when computing activity for a game page, fetch the full friend list once rather than checking friends individually
- Apply privacy filters at query time: maintain a bloom filter or set of opted-out user IDs that is checked before including a friend in results
- Handle the case where the social graph service is slow or unavailable by returning a cached (possibly stale) friend list or degrading gracefully with no friend activity
Suggested Approach
Step 1: Clarify Requirements
Ask about the freshness requirement: how quickly must a friend's new game session appear in the activity feed (real-time, 5 minutes, 15 minutes)? Clarify whether the feature shows activity for one specific game (on the game detail page) or aggregated across all games (on a friends dashboard). Ask about the friend list size distribution: what is the median, what is the maximum? Confirm whether "recent" means last 24 hours, last 7 days, or is configurable per game. Ask whether the system should rank which friends to display (closest friends first, or most recent activity first). Clarify if mutual friends or followers (non-mutual) are included.