How the User Tweet Entity Graph (UTEG) Generates "XXX Liked" Out-of-Network Recommendations
UTEG generates out-of-network "XXX Liked" recommendations by querying a real-time bipartite graph of user-tweet engagements using a weighted follow seed set, then filtering out any tweets authored by followed accounts to ensure strictly out-of-network results.
The User Tweet Entity Graph (UTEG) is the collaborative-filtering service that powers the "XXX Liked" section on Twitter's Home Timeline. According to the twitter/the-algorithm source code, this system traverses an in-memory graph of user interactions to surface tweets favorited by people you follow—but crucially excludes content authored by those same accounts. This article examines the exact implementation strategy, from graph traversal to final filtering, that produces these personalized out-of-network recommendations.
Building the Weighted Follow Graph Query
Constructing the Seed Set with Activity Weights
The process begins in UtegLikedByTweetsSource.scala where the client (TimelineRanker / Home Mixer) prepares a RecapQuery containing utegLikedByTweetsOptions. This includes a weighted follow seed set—the IDs of accounts the user follows, each weighted by recent activity levels. These weights reflect how engaged the user is with specific accounts, prioritizing signals from frequently interacted-with users.
The UTEGResultsTransform.makeUTEGQuery method then constructs the actual RecommendTweetEntityQuery object passed to the UTEG service. The seedUserIdsWithWeights field serves as the graph traversal entry point, while maxTweetResults caps the raw output (e.g., 800 candidates) before downstream filtering occurs.
Configuring Social Proof Parameters
To ensure the query targets only "liked" content, the implementation sets socialProofTypes to Seq(SocialProofType.Favorite). The query also specifies memory and computation limits through:
maxUserSocialProofSizeandmaxTweetSocialProofSize– caps on the number of social proof structures returnedminUserSocialProofSize– minimum threshold for inclusiontweetAuthors– optional author restrictions passed viaUTEGResultsTransform.requiredTweetAuthors
Traversing the Bipartite Graph for Social Proof
Once the query reaches the UTEG service, the TweetSocialProofRunner (implemented in GraphJet) traverses the in-memory bipartite graph connecting users to their tweet engagements. The runner searches for tweets with the highest weighted favorite counts from the seed user set.
This collaborative-filtering approach identifies content that has garnered significant engagement specifically from the user's follow graph, creating a personalized recommendation pool based on social proof rather than content similarity. The service returns TweetRecommendation objects containing tweet IDs and their associated favorite counts.
Enforcing Out-of-Network Boundaries
The Critical In-Network Filter
To ensure recommendations remain strictly out-of-network, the pipeline applies the UTEGRecommendationsFilter via UtegLikedByTweetsSource. The RemoveCandidatesAuthoredByWeightedFollowingsTransform explicitly drops any tweet where the author ID matches a seed user in the weighted followings map. This guarantees that "XXX Liked" recommendations show content liked by followed accounts but not authored by them.
Content Type Exclusions
Additional configurable gates in UtegLikedByTweetsSource allow fine-tuning of which interactions qualify as valid social proof:
ExcludeRetweetParam– Removes retweets from seed usersExcludeReplyParam– Filters out reply tweetsExcludeQuoteTweetParam– Excludes quote tweets
These parameters ensure the "Liked" label accurately represents original favorites rather than derivative content types.
Minimum Engagement Thresholds
The filter also enforces quality barriers through MinNumFavoritedByUserIdsParam, requiring tweets to meet a minimum number of unique favoriting users before inclusion. This prevents surface-level recommendations with insufficient social validation from entering the candidate pool.
Hydration, Scoring, and Pipeline Integration
After filtering, UTEGResultsTransform.apply attaches the remaining TweetRecommendation objects to the CandidateEnvelope as utegResults. The pipeline then executes several downstream transforms:
- Social proof hydration – Attaches metadata about which specific followed users favorited each tweet
- Earlybird score merging – Combines UTEG results with Earlybird search scores using configurable multipliers
- Truncation – The
combinedScoreTruncateTransformmerges and truncates the final list to the requested count
The UTEGCandidatePipelineConfigFactory wires this entire UTEG candidate source into Tweet Mixer's overall home-timeline pipeline, exposing the result as TweetCandidate objects containing only the tweet ID.
End-to-End Data Flow
| Step | Component | Key Action |
|---|---|---|
| 1 | Home Mixer → TimelineRanker | Builds RecapQuery with utegLikedByTweetsOptions containing the weighted follow set |
| 2 | TimelineRanker → UTEG | Calls UserTweetEntityGraphClient.findTweetRecommendations with RecommendTweetEntityQuery |
| 3 | UTEG Service | TweetSocialProofRunner traverses the bipartite graph for top favorited tweets |
| 4 | UTEG Filter | UTEGRecommendationsFilterBuilder removes in-network authored tweets and optional retweets/replies |
| 5 | Result Transformation | UTEGResultsTransform stores filtered results in CandidateEnvelope.utegResults |
| 6 | Scoring & Truncation | Merges Earlybird scores and truncates to final count |
| 7 | Response | Returns CandidateTweetsResult with out-of-network "XXX Liked" tweets |
Implementation Example
// Building the UTEG query in TimelineRanker
val utegQuery = RecommendTweetEntityQuery(
userId = recapQuery.userId,
displayLocation = TweetEntityDisplayLocation.HomeTimeline,
seedUserIdsWithWeights= recapQuery.utegLikedByTweetsOptions
.map(_.weightedFollowings).getOrElse(Map.empty),
maxTweetResults = utegCountProvider(recapQuery),
socialProofTypes = Seq(SocialProofType.Favorite),
maxUserSocialProofSize= Some(UTEGResultsTransform.MaxUserSocialProofSize),
maxTweetSocialProofSize= Some(UTEGResultsTransform.MaxTweetSocialProofSize),
minUserSocialProofSize= Some(UTEGResultsTransform.MinUserSocialProofSize)
)
// Calling the service and filtering
userTweetEntityGraphClient.findTweetRecommendations(utegQuery).map { recommendations =>
val filtered = recommendations.filterNot { rec =>
recapQuery.utegLikedByTweetsOptions.exists { opts =>
opts.weightedFollowings.contains(rec.authorId)
}
}
envelope.copy(utegResults = filtered.map(r => r.tweetId -> r).toMap)
}
Key Source Files
timelineranker/server/src/main/scala/com/twitter/timelineranker/uteg_liked_by_tweets/UTEGResultsTransform.scala– Constructs the query and attaches results to the candidate envelopetimelineranker/server/src/main/scala/com/twitter/timelineranker/uteg_liked_by_tweets/UtegLikedByTweetsSource.scala– Orchestrates the end-to-end flow including out-of-network filterstweet-mixer/server/src/main/scala/com/twitter/tweet_mixer/candidate_pipeline/UTEGCandidatePipelineConfigFactory.scala– Wires UTEG into the Tweet Mixer candidate pipelinerecos/user_tweet_entity_graph/TweetSocialProofRunner.scala– GraphJet implementation for graph traversal
Summary
- UTEG operates as a collaborative-filtering service using a real-time bipartite graph of user-tweet engagements
- Recommendations originate from a weighted follow seed set passed via
seedUserIdsWithWeightsinRecommendTweetEntityQuery - The system queries specifically for Favorite social proof types to generate "Liked" recommendations
- Strict out-of-network enforcement occurs through
RemoveCandidatesAuthoredByWeightedFollowingsTransform, which drops any tweet authored by followed accounts - Additional filters exclude retweets, replies, and quote-tweets based on request-time configuration parameters
- Results merge with Earlybird scores and pass through
UTEGResultsTransformbefore final truncation and serving
Frequently Asked Questions
How does UTEG ensure recommendations are strictly out-of-network?
After retrieving candidate tweets favorited by the user's followings, the RemoveCandidatesAuthoredByWeightedFollowingsTransform in UtegLikedByTweetsSource.scala explicitly filters out any tweet where the author ID exists in the weighted follow seed set. This guarantees that recommended content comes from accounts the user does not follow, even though the social proof (likes) comes from followed accounts.
What types of social proof does UTEG consider for "XXX Liked" recommendations?
For the specific "XXX Liked" use case, UTEG restricts the query to SocialProofType.Favorite only, as configured in UTEGResultsTransform.makeUTEGQuery. While the UTEG service supports multiple social proof types, the TimelineRanker explicitly requests only favorites to populate the "Liked" section accurately.
Why does UTEG use weighted followings rather than uniform followings?
The seedUserIdsWithWeights parameter incorporates recent engagement activity to weight followed accounts, allowing the graph traversal to prioritize signals from users the target user interacts with most frequently. This weighting improves recommendation relevance compared to treating all followed accounts equally.
Where in the codebase does the final scoring and truncation occur?
The combinedScoreTruncateTransform in UtegLikedByTweetsSource.scala handles final list truncation after merging UTEG results with Earlybird search scores. This transform applies configurable multipliers to Earlybird scores and truncates the combined candidate list to the maximum count requested by the Home Timeline mixer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →