# How the User Tweet Entity Graph (UTEG) Generates "XXX Liked" Out-of-Network Recommendations

> Discover how UTEG generates 'XXX Liked' out-of-network recommendations by querying a real-time user-tweet graph and applying unique filters for tailored content.

- Repository: [X (fka Twitter)/the-algorithm](https://github.com/twitter/the-algorithm)
- Tags: architecture
- Published: 2026-03-03

---

**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`](https://github.com/twitter/the-algorithm/blob/main/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:
- `maxUserSocialProofSize` and `maxTweetSocialProofSize` – caps on the number of social proof structures returned
- `minUserSocialProofSize` – minimum threshold for inclusion
- `tweetAuthors` – optional author restrictions passed via `UTEGResultsTransform.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 users
- `ExcludeReplyParam` – Filters out reply tweets  
- `ExcludeQuoteTweetParam` – 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:

1. **Social proof hydration** – Attaches metadata about which specific followed users favorited each tweet
2. **Earlybird score merging** – Combines UTEG results with Earlybird search scores using configurable multipliers
3. **Truncation** – The `combinedScoreTruncateTransform` merges 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

```scala
// 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`](https://github.com/twitter/the-algorithm/blob/main/timelineranker/server/src/main/scala/com/twitter/timelineranker/uteg_liked_by_tweets/UTEGResultsTransform.scala) – Constructs the query and attaches results to the candidate envelope
- [`timelineranker/server/src/main/scala/com/twitter/timelineranker/uteg_liked_by_tweets/UtegLikedByTweetsSource.scala`](https://github.com/twitter/the-algorithm/blob/main/timelineranker/server/src/main/scala/com/twitter/timelineranker/uteg_liked_by_tweets/UtegLikedByTweetsSource.scala) – Orchestrates the end-to-end flow including out-of-network filters
- [`tweet-mixer/server/src/main/scala/com/twitter/tweet_mixer/candidate_pipeline/UTEGCandidatePipelineConfigFactory.scala`](https://github.com/twitter/the-algorithm/blob/main/tweet-mixer/server/src/main/scala/com/twitter/tweet_mixer/candidate_pipeline/UTEGCandidatePipelineConfigFactory.scala) – Wires UTEG into the Tweet Mixer candidate pipeline
- [`recos/user_tweet_entity_graph/TweetSocialProofRunner.scala`](https://github.com/twitter/the-algorithm/blob/main/recos/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 `seedUserIdsWithWeights` in `RecommendTweetEntityQuery`
- 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 `UTEGResultsTransform` before 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`](https://github.com/twitter/the-algorithm/blob/main/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`](https://github.com/twitter/the-algorithm/blob/main/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.