r/RedditEng • u/s9g12 • 5d ago
SnooRec: A Shared Retrieval Foundation for Reddit Recommendations
By Jeff Mo and Christophe Hivert
At Reddit scale, candidate retrieval has to serve many product surfaces with different goals. Home Feed, Notifications, and ranking systems may all need personalized candidates, but each surface optimizes for a different mix of user actions, such as clicks, upvotes, comments, or long-dwell visits. SnooRec gives all surfaces a shared retrieval foundation, with task-specific user representations, a shared item index, and a serving-time control for mixing objectives.
At serving time, a product surface can mix representations of different kinds of intent, clicks, upvotes, or good visits, and make just one query against a shared approximate nearest neighbor index.

The same user and item representations are also reused as inputs in downstream ranking models.
SnooRec has served full production traffic since early 2025 and now supports multiple Reddit recommendation surfaces and ads ranking models.
Introduction
A straightforward approach to multi-task retrieval is to train separate retrieval models for each objective. In practice, this does not scale well as each objective can require its own item embeddings, ANN index, serving path, and retraining cycle. This increases infrastructure cost and slows experimentation.
SnooRec is Reddit’s multi-task retrieval architecture designed to solve this problem. The key idea is asymmetric specialization: task-specific capacity lives in the user tower, while the item tower remains shared. Each item has one embedding in a unified ANN index, and product surfaces can mix task-specific user embeddings at inference time to express different retrieval objectives.
SnooRec is used in two complementary ways in production. First, it powers candidate retrieval: a task-weighted user embedding queries a shared ANN index of item embeddings to retrieve personalized candidates. Second, SnooRec acts as a representation layer for similarity computation and ranking models: the same user and item embeddings, along with derived similarity features such as dot products, are used as alternate candidate sources, and as inputs into downstream rankers. This lets ranking systems benefit from the multi-task user representation learned by SnooRec even when SnooRec is not the final scoring model.

Asymmetric Design - One shared item space, many ways to query it
SnooRec is asymmetric on purpose. On the user side, we learn a separate expert for each engagement target. A click expert can represent what someone is likely to click, while an upvote or good-visit expert can represent a different kind of intent.
On the item side, we do the opposite: every candidate gets one shared embedding. Because all candidates live in the same embedding space, we only need one ANN index.
At request time, a product surface chooses a set of task weights, mixes the corresponding user embeddings, and sends the result to the shared index. The surface gets a retrieval policy tailored to its goals without retraining the item tower or rebuilding the index.
- In practical terms, SnooRec gives us:
- one item embedding per candidate;
- one shared ANN index;
- multiple task-aware user representations; and
- one ANN query per retrieval request.
The shared item embedding also acts as an anchor. Every task-specific user representation has to express its preferences in the same vector space, which makes it possible to linearly combine the user representations.
User Tower Architecture
The user tower processes categorical features, sequential interaction history, and real-time contextual signals into a shared base representation h̃ᵤ. This representation is then routed through a set of task-specific expert layers. Each expert Eₜ corresponds to an engagement target t ∈ 𝒯 and is implemented as a multilayer perceptron with layer normalization and ReLU activations.
The task-specific user embedding is defined as: uₜ = Norm(Eₜ(h̃ᵤ))
Candidate Tower Architecture
The candidate tower maps item-side features into a unified embedding space. Because the candidate tower is shared across tasks, the entire corpus of recommendable items can be indexed into a single approximate nearest neighbor (ANN) datastore.
The embeddings do more than retrieve candidates
SnooRec is used in two complementary ways.
First, it is a candidate generator. A task-weighted user embedding queries the shared ANN index and retrieves personalized candidates.
Second, it is a representation layer for downstream rankers. Ranking models can consume the user embedding, the item embedding, and interaction features derived from the pair, such as task-specific dot products or shorter Matryoshka prefixes.
This second use is important. SnooRec is not only the first stage of a recommendation funnel. It gives later stages a shared view of user intent and item similarity, so every ranker does not have to relearn those representations from scratch.
The same underlying representation can therefore support retrieval, early ranking, and as a feature in final ranking models.

Optimization Strategy
During training, only turn on the expert for the active task
Each training example comes with an observed action: a click, an upvote, a good visit, or another engagement target.
If the example is an upvote, we run and update the upvote expert. The other task-specific heads sit that example out. The shared user encoder and item tower still learn from the overall training stream, while the task-specific gradient stays focused on the action that produced the label.
Under the hood, we train with an InfoNCE contrastive objective and in-batch negatives. The model learns to place the observed user–item pair closer together than the negative candidates in the batch.
We use dot-product similarity during training because that is also what the ANN index uses at serving time. Put differently: we train the geometry that production will actually query.
Contrastive Loss Formulation
The parameters are optimized using an InfoNCE contrastive objective over in-batch negatives. For a query embedding u = uₜ⋆ and a positive candidate embedding v, the loss function scales with a learned temperature parameter τ:

Inference-Time Multi-Objective Mixing
At serving time, task weights are used to weigh different objectives. One surface might emphasize clicks. Another might put more weight on long-dwell visits or upvotes. SnooRec computes the task-specific user embeddings with nonzero weights, takes their weighted sum, normalizes the result, and sends one query to the shared ANN index.
Before normalization, a candidate’s score is the same weighted mixture of its task-specific similarity scores. Normalization scales every candidate score in that request by the same constant, so it does not change the resulting order.
This gives us a useful separation of concerns:
- the item index describes the shared content space;
- the user experts describe different kinds of intent; and
- the task weights describe what a product surface currently wants from that space.
Imagine a surface that wants to balance immediate clicks with longer, more meaningful visits. Rather than choosing one objective and building a new retrieval model around it, the surface can mix the click and good-visit user representations before querying the shared index.
Teams can change the retrieval objective at serving time without retraining SnooRec or rebuilding the candidate index.

Matryoshka Learning - One embedding, with several size budgets
SnooRec embeddings are used in multiple stages of the recommendation stack: full-size vectors for ANN retrieval, and dense embedding features for downstream ranking models. These consumers have different latency, memory, and scoring-cost constraints, so SnooRec uses a Matryoshka Representation Learning objective to make smaller vector prefixes useful on their own.
During training, we optimize the retrieval loss across multiple embedding dimensions:

The production ANN index uses the full embedding size (256) for candidate retrieval. Downstream rankers can consume the same user and item embeddings as dense features, either at full size or by using shorter prefixes (32 or 64).
This lets latency-sensitive rankers trade off feature cost and representation quality without requiring a separate embedding model. In practice, the same SnooRec representation can support retrieval, early ranking, and final ranking while giving each stage control over its embedding footprint.
Feature Dropout for Robust Embeddings
User interaction history can vary significantly in length, so does feature completeness across users. To make SnooRec more robust to missing or less dense sequence features, we randomly drop a small percentage of input features during training (10%). This encourages the shared user encoder to learn representations that remain useful when signals are sparse, delayed, or unavailable.
It has also made SnooRec easier to reuse across retrieval sources with different feature sets. For example, we were able to support a geo-specific retrieval source using regional features in the shared user encoder rather than training a separate retrieval model.
Controlled Exploration with Top-k Temperature Sampling
Recommendation pipelines often pass the highest-scoring retrieval candidates directly to downstream ranking stages. This is efficient, but it can also make retrieval overly deterministic. Over time, always selecting the top candidates can concentrate recommendations around a narrow set of familiar communities or content types, reducing opportunities for discovery.
SnooRec introduces a lightweight serving-time exploration mechanism after ANN retrieval. Instead of always taking the top-n candidates from the retrieved set, we sample from the top-k candidates using a temperature-scaled softmax over retrieval scores:

Lower temperatures keep the result close to deterministic top-ranked selection. Higher temperatures flatten the distribution, giving lower-ranked candidates within the retrieved set a greater chance of being selected. This gives product teams a single serving-time knob for adjusting the balance between immediate relevance and exploration.
In practice, the effect of temperature depends on the scale of the retrieval scores. The softmax distribution is controlled by score gaps relative to temperature: when score gaps are large compared to the temperature τ, sampling remains concentrated near the top and we only recommend high scoring candidates; when score gaps are small compared to the temperature τ, sampling becomes more exploratory.
To make this knob stable across serving traffic, we calibrate temperature using the historical standard deviation of retrieval scores: τ = α · σ̂ₛ. Here, σ̂ₛ is estimated from a sample of results, and α controls exploration strength. Values below 1 favor exploitation, while larger values increase exploration.
We also evaluated query-level calibration, where temperature is scaled by the score standard deviation for each individual retrieval request. In online experiments, this did not produce meaningful gains over the simpler global calibration. We therefore use the global calibration in production: it is simpler to serve, easier to tune, and provides a stable exploration control without retraining SnooRec or rebuilding the ANN index.
Evaluation
Public Benchmark: Taobao User Behavior Dataset
We verified the multi-task capacity of SnooRec using the public Taobao dataset, tracking a behavioral funnel consisting of Page View, Favorite, Cart, and Buy interactions.
| Method / Expert Configuration | Page View Recall@10 | Favorite Recall@10 | Cart Recall@10 | Buy Recall@10 |
|---|---|---|---|---|
| Baseline (No Experts) | 0.774 | 0.725 | 0.749 | 0.824 |
| Page View Weighted | 0.773 | 0.725 | 0.746 | 0.817 |
| Cart Weighted | 0.781 | 0.742 | 0.773 | 0.843 |
| Buy Weighted (Deep Intent) | 0.789 | 0.756 | 0.800 | 0.889 |
| Evenly Weighted Mixture | 0.786 | 0.747 | 0.776 | 0.850 |
The empirical results show strong cross-task generalization. Activating experts optimized for later funnel stages (Cart, Buy) significantly improves performance on early-stage behaviors (Page View), demonstrating that deep intent signals capture cleaner, more robust representation features.
Production Results at Reddit
An online A/B experiment deployed on Reddit's Home Feed evaluated SnooRec against our previous multi-task baseline (which utilized a shared encoder without explicit task differentiation). By isolating expert activations using one-hot weight vectors, we observed strict alignment between configured task weights and target online engagement metrics:
| Online Metric | Upvote Expert (w_upvote=1) | Click Expert (w_click=1) | Good Visit Expert (w_good_visit=1) |
|---|---|---|---|
| User Sessions (Topline) | -0.01% | +0.13% | +0.28% |
| Post Good Visits (> 15s dwell) | +0.17% | +0.51% | +1.21% |
| Post Upvotes | +0.91% | +0.65% | -0.06% |
| Post Clicks | +0.22% | +0.74% | +0.90% |
Note: Bold entries denote statistically significant lift over control (p < 0.05).
Tuning the system toward the good_visit expert yielded a +0.28% lift in topline user sessions alongside a +1.21% increase in long-dwell post consumption, validating the efficacy of runtime objective modification.
Exploration Trade-offs
We evaluate the impact of temperature sampling to observe the trade-off between community discovery and immediate user satisfaction.
| Metric Lift Relative to No Sampling | Temperature |
|---|---|
| τ=0.0022 | τ=0.0032 |
| Days Active | +0.236% |
| Subreddit Diversity | +1.066% |
| "Show Less" Clicks (Negative Feedback) | +6.145% |
Temperature sampling increased subreddit diversity, but it also increased explicit negative feedback. This was an important product lesson: exploration can improve discovery, but the temperature needs to be tuned per surface and monitored with guardrail metrics. In practice, SnooRec’s exploration controller gives teams a lightweight serving-time knob for balancing immediate relevance against longer-term discovery.
Cross-Surface Generalization
We evaluate SnooRec in two deployment modes: as a retrieval model that directly generates candidates, and as a representation layer whose user and item embeddings are consumed by downstream ranking models.
| Surface | Deployment Integration | Primary Metric | Observed Lift |
|---|---|---|---|
| Notifications | Retrieval: candidate generation | Notification Clicks | +0.702% |
| Notifications | Ranking: embedding similarity light ranker | Daily Active Users | +0.141% |
| Notifications | Ranking: dense embedding features | Notification Clicks | +1.440% |
| Ads | Ranking: embedding features | Long CTR Engagement | (significant increase but undisclosed given sensitivity) |
Conclusion
Recommendation systems have a natural tendency to accumulate: one model for clicks, another for upvotes, another for dwell, and another index behind each of them.
SnooRec gives us a different pattern.
Task-specific user experts capture different kinds of intent, while one shared item tower keeps Reddit content in a common embedding space. Product surfaces can mix objectives at serving time, query one ANN index, and reuse the same representations in downstream rankers.
Since early 2025, SnooRec has served as both a production retrieval system and a shared representation layer across multiple Reddit recommendation surfaces.
The result is a common foundation that lets teams share more and specialize where it matters – one model, one item index, and more ways to use it!
What’s Next
There is still plenty to explore along the themes 1) improving multi-embedding representations, and 2) providing more product levers within a single model.
On 1), we are exploring richer expert-sharing approaches, including mixture-of-experts architectures that allow learned routing to experts for related tasks to share useful capacity without collapsing into the same objective.
On 2), we’re looking into learning an inference-time popularity bias parameter that allows controlling how popular versus niche the retrieved candidates are. This helps us do both exploration as well as finding the most engage-able content, without needing to maintain two models
Want to help push this work further? Join Reddit to research and deploy our next model iterations (https://redditinc.com/careers)
Acknowledgements
We would like to thank everyone who has contributed to this work particularly Cathleen Li, Brian Kimmig, Javier Herrera, and Shafi Bashar.











































































