The Request Lifecycle
The For You feed is generated through a highly orchestrated sequence of events managed by Home Mixer. This section walks you through the lifecycle of a single request, from the moment a user opens their app to the final delivery of a ranked feed.
Phase 1: Orchestration and Hydration
The lifecycle begins when a user client sends a gRPC request to the Home Mixer. This service acts as the central orchestrator for the entire recommendation pipeline.
- Request Ingestion: The
HomeMixerServerreceives the request. It extracts theUser IDand current device context. - User Hydration: Before candidates can be retrieved, the system must understand the user's current state. The Query Hydrator fetches:
- User Action Sequence: A history of recent interactions (likes, replies, shares).
- User Features: High-level embeddings that represent user interests.
- Following List: Managed by the StratoClient, this identifies the "In-Network" universe for that specific user.
Phase 2: Candidate Retrieval
To populate the feed, the system simultaneously pulls from two distinct sources to gather approximately 1,000–1,500 candidate posts.
In-Network Retrieval (Thunder)
The system queries Thunder, the in-memory post store.
- Search: Thunder looks up posts created by the accounts the user follows.
- Real-time Processing: Since Thunder consumes from a Kafka stream (via
tweet_events_listener), it provides the most recent "In-Network" content, often appearing within seconds of being posted.
Out-of-Network Retrieval (Phoenix)
To discover new content, the system uses the Phoenix Retrieval Model, a two-tower architecture:
- User Tower: Encodes the hydrated user context into a normalized vector.
- Candidate Tower: Projects a global corpus of posts into the same embedding space.
- Similarity Search: The system performs an Approximate Nearest Neighbor (ANN) search to find posts that align with the user’s embedding, even if they don't follow the author.
Phase 3: Heavy Ranking with Phoenix
Once the candidates are collected, they are passed to the Phoenix Ranker. This is where the Grok-based transformer performs the "heavy lifting."
1. Data Preparation (RecsysBatch)
The system assembles a RecsysBatch containing:
- User Hashes: Identifiers for the requesting user.
- History Sequences: The user's recent engagement history.
- Candidate Hashes: Identifiers for the post and the author of each candidate.
2. Transformer Scoring
The batch is fed into the Phoenix Transformer. Unlike traditional models that use hand-engineered features, Phoenix relies on:
- Multi-head Attention: The model uses a specific
recsys_attn_maskthat allows candidate posts to attend to the user's history while preventing candidates from attending to each other. - Probability Prediction: The model outputs logits representing the probability of various engagements (Like, Retweet, Reply).
# The model produces logits for each candidate based on user history
outputs = phoenix_model.apply(params, recsys_batch, recsys_embeddings)
final_scores = calculate_weighted_engagement(outputs.logits)
Phase 4: Filtering and Post-Processing
After scoring, the Candidate Pipeline applies a series of heuristics and filters to ensure the feed is safe, diverse, and relevant.
- Visibility Filtering: Removes posts from blocked or muted accounts, and applies safety labels (e.g., NSFW filtering).
- Deduplication: If the same post was retrieved by both Thunder and Phoenix, the duplicates are collapsed.
- Fatigue Management: Filters out posts the user has already seen in recent sessions to ensure the feed feels fresh.
- Author Diversity: Limits the number of consecutive posts from the same author to prevent "clustering."
Phase 5: Delivery
The final list of ranked and filtered ScoredPosts is packaged by the Home Mixer and returned to the client.
| Stage | Responsibility | Output | | :--- | :--- | :--- | | Hydration | Context Gathering | User Embeddings & History | | Retrieval | Candidate Discovery | ~1,500 Raw Posts | | Ranking | Phoenix (Grok) | Engagement Probabilities | | Filtering | Pipeline Logic | Clean, Diverse Feed |
The user's client then renders these posts, and any subsequent interaction (a "Like" or "Reply") is sent back to the data stream, immediately hydrating the next request's lifecycle.