# How the User User Graph (UUG) Leverages the Follow Graph for Recommendations

> Discover how the User User Graph (UUG) uses your recent follows and Twitter's GraphJet engine to deliver personalized and effective recommendations. Enhance your user experience today.

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

---

**The User User Graph generates "who-to-follow" recommendations by using a user's recent follow actions as weighted seeds for collaborative-filtering traversals through Twitter's in-memory GraphJet engine.**

The User User Graph (UUG) is a critical recommendation service within the `twitter/the-algorithm` repository designed to surface relevant accounts based on social graph connectivity. By analyzing recent follow patterns as high-signal starting points, UUG performs real-time traversals over the follow graph to identify candidates with strong social proof connections to the requesting user.

## Seed Selection from the Follow Graph

UUG initiates its recommendation pipeline by extracting **seed user IDs** directly from the requester’s recent follow activity. When the `UserUserGraphCandidateSource` receives a recommendation request, it accesses `target.recentFollowedUserIds` to build the initial traversal set.

In [`follow-recommendations-service/common/src/main/scala/com/twitter/follow_recommendations/common/candidate_sources/user_user_graph/UserUserGraphCandidateSource.scala`](https://github.com/twitter/the-algorithm/blob/main/follow-recommendations-service/common/src/main/scala/com/twitter/follow_recommendations/common/candidate_sources/user_user_graph/UserUserGraphCandidateSource.scala) (lines 65-73), the candidate source constructs a `RecommendUserRequest` using these recent follows as the foundation for collaborative filtering. This approach treats accounts the user has recently chosen to follow as implicit interest indicators, creating a personalized subgraph for exploration.

## Weighted Seed Mapping and Social Proof

Before traversal begins, UUG converts the raw list of followed users into a weighted map that influences downstream scoring. The source code assigns each seed a `DefaultSeedWeight`, creating a `seedsWithWeights` parameter that controls how much influence each starting node exerts during graph propagation.

As shown in lines 68-71 of [`UserUserGraphCandidateSource.scala`](https://github.com/twitter/the-algorithm/blob/main/UserUserGraphCandidateSource.scala), this weighting mechanism ensures that recent follows contribute proportionally to the aggregation of "social proof"—the metric that counts how many of the seed’s followers also engage with candidate users. Higher weights amplify the significance of specific follow relationships during the candidate scoring phase.

## GraphJet Traversal and Scoring

Once the weighted seeds are prepared, UUG delegates to the **GraphJet** in-memory graph engine for high-performance traversal. The service entry point in [`src/scala/com/twitter/recos/user_user_graph/UserUserGraph.scala`](https://github.com/twitter/the-algorithm/blob/main/src/scala/com/twitter/recos/user_user_graph/UserUserGraph.scala) (lines 13-18) exposes a Finagle Thrift endpoint that forwards requests to the `RecommendUsersHandler`.

GraphJet traverses the **user-user relationship graph**—which encodes follow, favorite, and interaction edges—starting from the weighted seeds. It aggregates scores for candidate users based on the number and cumulative weight of paths connecting the seeds to each candidate. Accounts that appear frequently in the follow networks of the seed users receive higher relevance scores.

After traversal completes, UUG returns `RecommendedUser` objects sorted by descending score. The candidate source performs final ranking using `-_.score` (lines 50-53 of [`UserUserGraphCandidateSource.scala`](https://github.com/twitter/the-algorithm/blob/main/UserUserGraphCandidateSource.scala)), surfacing users with the strongest follow-graph connectivity to the requester’s recent activity.

## Implementation Example

The following Scala code demonstrates how UUG constructs a recommendation request from recent follow data:

```scala
import com.twitter.recos.user_user_graph.thriftscala._
import com.twitter.follow_recommendations.common.candidate_sources.user_user_graph._

def buildUugRequest(
  requesterId: Long,
  recentFollowedIds: Seq[Long],
  excludedIds: Set[Long],
  maxResults: Int
): RecommendUserRequest = {

  val seeds = recentFollowedIds.map(_ -> UserUserGraphCandidateSource.DefaultSeedWeight).toMap
  RecommendUserRequest(
    requesterId = requesterId,
    displayLocation = RecommendUserDisplayLocation.TimelineHome,
    seedsWithWeights = seeds,
    excludedUserIds = Some(excludedIds),
    maxNumResults = Some(maxResults),
    maxNumSocialProofs = Some(UserUserGraphCandidateSource.MaxNumSocialProofs),
    minUserPerSocialProof = Some(UserUserGraphCandidateSource.MinUserPerSocialProof),
    socialProofTypes = Some(Seq(UserUserGraphCandidateSource.SocialProofType))
  )
}

```

To fetch recommendations via the candidate source pipeline:

```scala
val candidateSource = inject[UserUserGraphCandidateSource]
val target = UserUserGraphCandidateSource.Target(
  userId = Some(requesterId),
  recentFollowedUserIds = Some(recentFollowedIds),
  excludedUserIds = excludedIds,
  params = requestParams
)

val candidatesFut = candidateSource(target) // Returns Stitch[Seq[CandidateUser]]

```

## Key Source Files

- **[`UserUserGraph.scala`](https://github.com/twitter/the-algorithm/blob/main/UserUserGraph.scala)** (`src/scala/com/twitter/recos/user_user_graph/`): The Thrift service wrapper that exposes the `recommendUsers` RPC and delegates to `RecommendUsersHandler`.

- **[`UserUserGraphCandidateSource.scala`](https://github.com/twitter/the-algorithm/blob/main/UserUserGraphCandidateSource.scala)** (`follow-recommendations-service/common/src/main/scala/com/twitter/follow_recommendations/common/candidate_sources/user_user_graph/`): Builds the `RecommendUserRequest` from recent follow activity, invokes the UUG fetcher, and converts responses to `CandidateUser` objects.

- **GraphJet repository**: The external high-performance in-memory graph engine linked in the UUG README that powers the actual traversal and scoring logic.

## Summary

- UUG uses `recentFollowedUserIds` as weighted traversal seeds to personalize the recommendation space.
- The **follow graph** provides the foundational edge data for seed selection and social proof calculation.
- **GraphJet** performs fast in-memory traversals over the user-user relationship graph using the weighted seed map.
- Results are ranked by connection strength, prioritizing candidates with multiple high-weight paths from the user's recent follows.

## Frequently Asked Questions

### How does UUG differ from other candidate sources in the follow recommendations service?

While other candidate sources might rely on content similarity or popularity metrics, UUG specifically leverages the **structural properties of the follow graph**. It performs collaborative filtering by assuming that users who recently followed similar accounts share interests, making it particularly effective for "who-to-follow" suggestions based on social proximity rather than content analysis.

### What determines the weight assigned to each seed user in the follow graph?

UUG assigns a `DefaultSeedWeight` to every recent follow uniformly during request construction. This weight influences how much each seed contributes to the social proof aggregation during GraphJet traversal. The uniform weighting ensures all recent follows contribute equally to the candidate scoring, though the underlying GraphJet algorithm may apply additional edge-specific weights during traversal.

### Can UUG recommendations exclude specific users or account types?

Yes. The `RecommendUserRequest` accepts an `excludedUserIds` parameter that prevents specific accounts from appearing in results. The `UserUserGraphCandidateSource` passes these exclusions directly to the UUG service, ensuring filtered candidates are removed from the final ranked list before returning recommendations to the user.

### How does the GraphJet engine handle real-time updates to the follow graph?

GraphJet operates as an in-memory graph engine that ingests real-time interaction edges, including follows and favorites. While the UUG service itself focuses on the traversal logic, GraphJet's architecture supports rapid edge ingestion, allowing the follow graph used for seed selection and traversal to reflect recent user activity with minimal latency.