Why Friend Bubbles Matter
Facebook Reels introduced Friend Bubbles to surface content your friends have liked or reacted to. The goal is simple: make social discovery effortless and turn passive scrolling into shared moments. But behind that small UI bubble lies a complex distributed system that blends social-graph signals, video relevance, and real-time performance constraints.
This tutorial walks through the core components: user-user closeness models, friend-aware ranking, and the client infrastructure that keeps Reels fast. We'll focus on the practical engineering decisions that made this feature work at Meta’s scale.
Source: This analysis is based on Meta Engineering's official deep dive.
System Architecture Overview
The friend bubbles pipeline has two main pillars:
- Viewer-Friend Closeness — Which friends' interactions matter most?
- Video Relevance — Which videos, among those friends interacted with, should be shown?
These two components feed into a multi-stage ranking funnel that outputs a personalized set of Reels with friend bubbles.

1. Viewer-Friend Closeness: Two Complementary Models
Friend bubbles use two ML models to estimate relationship strength:
Survey-Based Closeness Model
- Trained on lightweight binary surveys: "Do you feel close to this friend in real life?"
- Features: mutual friends, interaction frequency, shared posts, location similarity
- Runs weekly inference over trillions of person-to-person connections
On-Platform Activity Model
- Trained on real-time signals: likes, comments, reshares when bubbles are shown
- Captures contextual closeness — how likely a viewer is to value content from a specific friend
# Pseudocode for closeness score aggregation
# 주석: 두 모델의 점수를 결합하여 최종 친밀도 점수 계산
def compute_closeness(user_a, user_b):
survey_score = survey_model.predict(user_a, user_b) # 0.0 ~ 1.0
activity_score = activity_model.predict(user_a, user_b) # 0.0 ~ 1.0
# 가중 평균 (survey 모델에 더 높은 가중치 부여)
final_score = 0.7 * survey_score + 0.3 * activity_score
return final_score
Key Insight: Connection quality > quantity. Showing more bubbles doesn't increase engagement — showing the right bubbles does.
2. Video Relevance: Making the Ranking System Friend-Content Aware
Expanding the Top of Funnel
- Explicitly retrieve videos that close friends have interacted with
- Without this, high-quality friend content may never enter the ranking pipeline
Continuous Feedback Loop
- Add friend-bubble interaction signals as features in both early-stage and late-stage ranking models
- New training tasks: learn relationship between closeness and viewer interest
# Pseudocode for friend-aware ranking objective
# 주석: 친구 버블 상호작용 신호를 기존 랭킹 공식에 통합
def rank_video(video, viewer, friend_closeness_scores):
base_score = video_quality_model(video)
friend_bonus = 0
for friend_id, closeness in friend_closeness_scores.items():
if friend_id in video.interacted_friends:
friend_bonus += closeness * 0.15 # 가중치 조정 가능
# P(engagement | bubble) 조건부 확률 고려
bubble_engagement_prob = engagement_model.predict(video, viewer)
final_score = base_score + friend_bonus + 0.1 * bubble_engagement_prob
return final_score
Dual Optimization
- Social connection: help people discover videos their friends like
- Content quality: maintain high video relevance
- Trade-off managed by tunable weights in the ranking formula

3. Client Infrastructure: Performance at Reels Scale
Adding metadata to a performance-sensitive surface like Reels is risky. Three non-negotiable constraints:
- Smooth scrolling — no jank
- No load latency regressions — videos must start instantly
- Low CPU overhead — especially on low-end devices
Key Optimizations
| Optimization | How It Works | Impact |
|---|---|---|
| Prefetch pinning | Friend-bubble metadata fetched alongside video metadata in the same prefetch window | Eliminates redundant network requests |
| Conditional animation | Animation disabled during scrolling; turned off entirely on low-end devices | Preserves scroll responsiveness |
| Reuse cached results | Stable data (e.g., closeness scores) cached and reused | Avoids duplicate CPU work |
# Pseudocode for conditional animation logic
# 주석: 스크롤 중에는 애니메이션 비활성화, 저사양 기기에서는 완전히 끔
def should_animate(device_tier, is_scrolling):
if is_scrolling:
return False # 스크롤 중에는 애니메이션 끄기
if device_tier == 'low_end':
return False # 저사양 기기에서는 항상 끄기
return True
Limitations & Cautions
- Cold start problem: Users with small friend graphs see fewer bubbles, making the feature less useful for new accounts
- Privacy considerations: Closeness models rely on sensitive social graph data; users may not want their interactions surfaced
- Bias amplification: If closeness models over-index on strong ties, users may miss diverse content from weaker connections
Next Steps
- Explore how to extend friend-driven recommendations to other surfaces (Feed, Groups, Marketplace)
- Investigate graph neural networks for more accurate closeness prediction
- Read our related guide on building AI workflows visually with Daggr
Summary
Friend bubbles demonstrate how machine learning + social graph can create meaningful discovery experiences. The architecture balances:
- Two complementary closeness models (survey-based + activity-based)
- Friend-aware ranking with a continuous feedback loop
- Performance-first client infrastructure that preserves Reels’ core UX
When done right, social discovery doesn't just increase engagement — it strengthens real-world connections. And that's the ultimate metric.

Further Reading
- A Deep Dive into PyTorch Distributed Communication — Learn how to build distributed ML systems that power features like friend bubbles.
- Meta Engineering Blog: Friend Bubbles: Enhancing Social Discovery on Facebook Reels