Guide · AI and GenAI
Feed Ranking System Design: Engagement vs Wellbeing
24 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- Feed ranking system design is the plan for choosing and ordering posts so a feed shows what people value, not only what they react to. You predict several reactions per post, then combine them.
- Most feeds work in stages. Candidate sources, cheap queries that each find one kind of post, gather a few thousand posts. A light ranker, a small fast model, trims them. A heavy ranker scores the rest, and a re-ranker builds the page.
- The heavy ranker is multi-task: one model that predicts likes, comments, shares, hides and reports at once. A value model, a weighted sum that product people set, turns those chances into one score.
- Two extra signals push down posts people react to but regret: an integrity score, the risk that a post is harmful, and a wellbeing score from a short survey. Changes ship only after an A/B test, a live experiment on a random slice of users.
- Beginners can stop after the wellbeing section. Engineers then get runnable checks: a calibration test that catches a model output predicting double the real hide rate, and a feedback-loop simulation. In it, where unseen posts start with a score of zero, 5% random slots found 7 or 8 of the 10 best posts instead of 0 or 1.
What goes wrong when a feed is ranked only for engagement?
A feed ranked only for engagement shows whatever people react to most. People often react most to posts that annoy or upset them, so comments go up while trust goes down. Avoiding that trap is the core job of feed ranking system design.
Picture a common setup. A neighbourhood social app in Surat lets people post about lost pets, water cuts, housing society meetings and local events. About 4 lakh (400,000) people use it each month. The setup is made up, but the problem is real.
Last year the team ranked the feed by one engagement score, built from the predicted chances of a like, a comment and a share. In three months, comments per user rose 22%. Then other numbers moved the wrong way (all made up).
- Reports of abusive posts doubled. Most came from one long, angry argument about parking that the feed kept pushing to the top.
- Hides rose by a third. A hide is when a person taps "Show me less of this."
- In a monthly survey, the share of people who said the app made their area feel friendlier fell from 61% to 48%.
- First-time posters got fewer replies, because the top of the feed was busy with fights. Many never posted again.
The product head summed it up in one question. Are we showing people what they want, or what they cannot ignore?
A similar pattern has been measured on a real platform, for political posts. A 2023 study compared one large social platform's engagement-ranked feed with a newest-first feed. The engagement feed amplified angry posts hostile to the other political side, and users said they did not prefer the political posts it picked.
This guide covers the machine learning (ML) side: candidates, predictions, the value model, wellbeing signals, testing and feedback loops. Storing posts and copying them into each follower's feed, called fan-out, is a backend topic covered in our news feed system design guide.
Which words do you need before learning feed ranking?
You need six words: candidate, impression, label, multi-task model, value model and guardrail metric. Each gets a plain meaning and an example from the neighbourhood app.
Candidate. A candidate is any post that might go into one person's feed right now. Example: when someone opens the app, about 2,000 recent posts from their area and groups are candidates.
Impression. An impression is one post shown to one person once. It is the basic unit of feed data.
Label. A label is what actually happened after an impression, written as 1 or 0. Example: liked 1, hidden 0, reported 0.
Multi-task model. A multi-task model is one ML model that predicts several things at once. Here it gives, for each candidate, the chance of a like, a comment, a share, a hide and a report.
Value model. A value model is a formula that turns those predicted chances into one score, using a weight for each action. A report gets a large negative weight, because one report usually means someone was hurt.
Guardrail metric. A guardrail metric is a number that must not get worse when you ship a change, even if your main goal improves. Example: reports per 1,000 impressions.
What is feed ranking system design?
Feed ranking system design is the plan for how a feed picks, scores and orders posts for each person, and how you check that the order is good. It is mostly an ML problem with a strict time limit.
Think of a TV channel planning its evening schedule. If the programming head looks only at last night's ratings, every slot fills with shouting debate shows. People watch, but they switch off feeling worse.
A good programming head looks at more than ratings. Map the parts like this. Ratings are the like and comment predictions, and viewer letters are the survey. Broadcast rules are the integrity checks, and a trial slot for new shows is exploration, trying posts the ranker would skip.
Where the picture breaks: a channel makes one schedule for everyone, once a day. A feed builds a different order for every person, every time they open the app, in a fraction of a second.
Here is the app's ranking pipeline. Follow the arrows from the person opening the app to the finished feed. Notice how the number of posts shrinks at each stage.
The feed ranking pipeline in the running example
Drag to exploreEach stage works on fewer posts with a more careful model. Notice the logger feeding the next night's training. Post counts are made up.
Diagram connections:
- Person opens the app to Candidate sources
- Candidate sources to Integrity filter (About 2,000 posts)
- Integrity filter to Light ranker
- Light ranker to Heavy ranker (Best 300)
- Heavy ranker to Value model (Predicted chances)
- Value model to Re-ranker (One score per post)
- Re-ranker to Finished feed (Top 20)
- Finished feed to Event logger (Views and actions)
- Event logger to Heavy ranker (Nightly retraining)
- Person opens the app: Asks for the first 20 posts
- Candidate sources: Gather about 2,000 posts from four sources
- Integrity filter: Drops removed posts and blocked authors
- Light ranker: Small fast model keeps the best 300
- Heavy ranker: Multi-task model predicts each action
- Value model: Weights turn predictions into one score
- Re-ranker: Caps per author and for heated posts
- Finished feed: The order the person actually sees
- Event logger: Saves impressions, positions and actions
Why stages? The heavy model is too slow to score 2,000 posts while someone waits. In this setup the whole ranking budget is about 150 milliseconds (made up), so cheap steps cut the list first and the careful model sees only 300 posts.
The integrity filter is the first cheap step. It drops posts that moderators already removed and posts from authors the viewer blocked.
Where do the posts in a feed come from?
Posts come from several candidate sources, each a cheap query that finds one kind of possibly useful post. A fixed share of slots per source stops any one source from flooding the list.
The app uses four sources. The shares are the team's starting point, tuned later with tests (made up).
- Followed: recent posts from people and groups the person follows, such as their housing society group. About 50% of candidates.
- Nearby: posts from within 3 km of home, even from strangers, such as a water cut notice. About 30%.
- Popular in the city: posts whose replies are growing fast today, such as a flood warning. About 15%.
- Fresh: new posts with few views yet, including first posts from new members. About 5%, and the feedback-loop section shows why this small source matters.
Finding candidates by similarity between people and posts is covered in our recommendation system design guide. This guide starts once the candidates exist.
The light ranker then trims 2,000 candidates to 300. It can be a small model, such as a few hundred small decision trees (chains of yes or no questions about a post). It reads only quick features, the input numbers a model uses, like post age and distance.
Its job is recall: keep the good posts, even if their order is rough. The careful ordering comes next.
How does a multi-task model predict likes, comments, hides and reports?
A multi-task model has shared layers that learn general patterns, then a small output part, called a head, for each action. Each head gives one probability, such as a 4% chance this person hides this post.
Why one model instead of five? Reports are rare, maybe a few per 10,000 impressions here (made up). A report-only model would have few examples and could overfit, memorising those few rows instead of learning patterns. A shared model lets the report head reuse patterns learned from millions of likes and comments.
An overview of multi-task learning calls this hard parameter sharing: the inner layers are shared by all tasks, with one output layer per task. It says sharing lowers the risk of overfitting. It also warns that an unrelated task can make another task worse, called negative transfer.
The diagram shows the shape. Look at how every head starts from the same shared layers, and how all heads end at the value model.
The multi-task heavy ranker
Drag to exploreOne shared body, one head per action. Notice that the rare report head sits on the same shared layers as the busy like head.
Diagram connections:
- Features to Shared layers
- Shared layers to Like head
- Shared layers to Comment head
- Shared layers to Hide head
- Shared layers to Report head
- Shared layers to Worth-your-time head
- Like head to Value model
- Comment head to Value model
- Hide head to Value model
- Report head to Value model
- Worth-your-time head to Value model
- Features: Post, viewer, their history, time of day
- Shared layers: Learn patterns common to every action
- Like head: Chance of a like
- Comment head: Chance of a comment
- Hide head: Chance of show me less
- Report head: Chance of a report
- Worth-your-time head: Trained on survey answers
- Value model: Weighted sum of all heads
Training data comes from the event logger. Each impression becomes one row: the features at the moment it was shown, plus a 1 or 0 label for each action within 24 hours. One useful feature is how often this viewer replied to this author before.
How does a value model turn predictions into one ranking score?
A value model multiplies each predicted chance by a weight that says how much that action is worth, then adds them up. Good actions get positive weights, and hides and reports get negative ones.
In this design, the ranking model does not learn these weights. They start as a product decision and get tuned with A/B tests. Here the team agrees that a comment is worth four likes, because it starts a conversation between neighbours, and that a report costs fifty likes.
Here is the team's value model in Python. The input p holds the predicted chances from the heads. The input integrity_risk is a 0 to 1 score from a separate classifier, a model that sorts posts into labels such as borderline or fine. The input worth_time comes from the survey-trained head.
GOOD = {"like": 1.0, "comment": 4.0, "share": 6.0}
BAD = {"hide": 5.0, "report": 50.0}
def value_score(p, integrity_risk, worth_time):
good = sum(w * p[action] for action, w in GOOD.items())
bad = sum(w * p[action] for action, w in BAD.items())
good *= 1.0 - 0.8 * integrity_risk # demote borderline posts
return good - bad + 0.5 * worth_time # reward posts people value
argument = {"like": 0.10, "comment": 0.12, "share": 0.02,
"hide": 0.04, "report": 0.006}
camp = {"like": 0.18, "comment": 0.03, "share": 0.03,
"hide": 0.005, "report": 0.0005}
print(round(value_score(argument, integrity_risk=0.6, worth_time=0.10), 2))
print(round(value_score(camp, integrity_risk=0.02, worth_time=0.60), 2))Run it with Python 3 and it prints -0.09 for the parking argument and 0.72 for a blood donation camp post. Both numbers are unitless scores; only their order matters.
What just happened? The demotion multiplied only the good part of the argument's score, by 1 minus 0.48. The last line added the wellbeing term on its own, so a post can rise because people value it, not only because they react.
The table compares the two posts. Post A is the parking argument. Post B announces a blood donation camp at a community hall.
| Signal | Post A: parking argument | Post B: blood donation camp |
|---|---|---|
| Chance of a like | 10% | 18% |
| Chance of a comment | 12% | 3% |
| Chance of a share | 2% | 3% |
| Chance of a hide | 4% | 0.5% |
| Chance of a report | 0.6% | 0.05% |
| Integrity risk | 0.6 | 0.02 |
| Worth-your-time chance | 10% | 60% |
| Old score (good part only, same weights) | 0.70 | 0.48 |
| New value score | -0.09 | 0.72 |
Under the old ranking, the argument wins because it draws comments. Under the new value model, the camp wins clearly. The argument still appears for people who follow that society group, but lower down.
How do integrity and wellbeing signals change what people see?
Integrity signals estimate how likely a post is to cause harm, and push risky posts down. Wellbeing signals estimate whether people are glad they saw a post, and push those up. Both work inside ranking, not as a delete button.
Removing posts that break the rules is content moderation, covered in our content moderation system design guide. Ranking handles the grey zone. A borderline post breaks no rule but sits close to one, like a heated post naming a neighbour. It stays up, but it gets demoted.
Wellbeing is harder, because no tap measures it directly. The team shows a one-question survey to a small random sample of people after some sessions. The question reads, "Was this post worth your time?"
The answers train the worth-your-time head. Only a tiny share of people answer, but the head learns to predict the answer for everyone. People who answer surveys may differ from those who skip them, so compare the answering group with all users.
Research describes this direction. A 2021 paper lists real recommender systems changed to serve values such as well-being, time well spent and factual accuracy. It calls the usual method values engineering: building classifiers from human-labelled data, one problem at a time.
A 2022 synthesis by 21 researchers lists open problems that include feedback that is not based on behaviour and optimising for long-term outcomes. A survey answer is one such non-behavioural signal.
The 2023 study from the opening adds a caution. Ranking by what users said they wanted cut angry, hostile content, but it could also show people more posts that agree with their existing views.
How do you correct position bias in feed training data?
Position bias means people tap the top of a feed more, whatever the post. To correct it, give the model each post's slot as a training feature, then set that feature to one fixed value for every post when ranking.
The other common fix weights each like by one divided by the chance its slot was seen.
Why is it needed? Without a fix, the model credits the post for likes the slot earned. A 2016 paper on training ranking models from clicks says position bias in search rankings strongly influences how many clicks a result receives.
That paper's fix is propensity weighting. The propensity is the chance a slot gets looked at, and each click counts more when its slot was rarely seen.
We tested both fixes with scikit-learn 1.9.1 on 400,000 made-up rows. Each like depended on the post's quality and its slot. The old feed sorted by newness, which had no effect on how much people liked a post.
- Without position, the model gave newness a weight of 1.01, larger than quality's 0.69. It learned the old feed's habit, not people's taste.
- With position as a feature, newness fell to 0.04. Scored at one fixed slot, the ranking followed quality alone.
- Weighting each like by 1 divided by its slot's chance of being seen cut newness to 0.08.
This toy is a check of the idea, not of your data. Our search ranking guide explains the same two fixes for search results.
How do you check that each head's probabilities are honest?
Group impressions by predicted chance and compare each group's average prediction with what really happened. This is a calibration check. If the hide head says 4%, about 4 in 100 such impressions should really be hidden.
It matters because the value model multiplies probabilities by weights. A hide head that doubles its guesses quietly doubles the hide penalty.
A ranking score called AUC does not catch this. AUC is the chance that the model scores a random positive example above a random negative one. Doubling every prediction keeps the order, so AUC stays the same.
Here is a check you can run after every retrain. It uses numpy and builds a deliberately broken hide head that says double the truth.
import numpy as np
def calibration_check(predicted, hidden, edges=(0, 0.01, 0.03, 0.1, 1)):
for lo, hi in zip(edges[:-1], edges[1:]):
rows = (predicted >= lo) & (predicted < hi)
print(f"predicted {lo:.0%}-{hi:.0%}: says {predicted[rows].mean():.1%}, "
f"real {hidden[rows].mean():.1%}, rows {rows.sum()}")
rng = np.random.default_rng(7)
real_chance = rng.beta(1, 40, 200_000) # true hide chance per impression
hidden = rng.random(200_000) < real_chance # what people actually did
calibration_check(real_chance * 2, hidden) # a head that says double the truthWith numpy 2.5.4 it prints these four lines. Every group says about twice the real rate or more, the signature of an over-confident head.
predicted 0%-1%: says 0.5%, real 0.2%, rows 36171
predicted 1%-3%: says 1.9%, real 1.0%, rows 54525
predicted 3%-10%: says 5.7%, real 2.9%, rows 83683
predicted 10%-100%: says 14.6%, real 7.3%, rows 25621In our run, the honest head and the doubled head both scored an AUC of 0.7519. Only the calibration table showed the problem.
How does the re-ranker build a healthy page?
The re-ranker walks down the scored list and skips posts that would break page rules, such as too many posts from one author. Scoring posts one by one cannot see the page as a whole, so this last step can.
Here is the team's version with a small test. Each post has an id, an author, a score and an is_heated flag. The flag is set when the integrity risk passes a threshold.
from collections import namedtuple
Post = namedtuple("Post", "id author score is_heated")
def build_page(scored_posts, top_n=20, per_author=2, heated_max=1):
page, by_author, heated = [], {}, 0
for post in sorted(scored_posts, key=lambda p: p.score, reverse=True):
if by_author.get(post.author, 0) >= per_author:
continue
if post.is_heated and heated >= heated_max:
continue
page.append(post)
by_author[post.author] = by_author.get(post.author, 0) + 1
heated += int(post.is_heated)
if len(page) == top_n:
break
return page
posts = [Post("p1", "author_a", 0.9, True), Post("p2", "author_a", 0.8, False),
Post("p3", "author_a", 0.7, False), Post("p4", "author_b", 0.6, True),
Post("p5", "author_c", 0.5, False)]
print([p.id for p in build_page(posts, top_n=4)])It prints ['p1', 'p2', 'p5']. Post p3 hit the two-per-author cap, and p4 was a second heated post. In a real feed the loop keeps walking down the list until it fills 20 slots.
How do you test a feed ranking model offline and online?
Offline tests check the model's predictions on past logged data before any user sees it. Online A/B tests then show the new ranking to a random slice of users and compare outcomes. You need both, because each misses things.
Offline, the team checks each head's AUC and calibration on yesterday's impressions. These checks are cheap and catch broken models fast.
But offline data has a blind spot. It only holds reactions to posts the old ranker chose to show. Nobody can see how people would have reacted to a post that was never shown, so offline gains do not always hold online.
Online, an A/B test splits users at random into a control group on the old ranker and a treatment group on the new one. The goal metric here is daily users who post or comment. Ship only when it improves and no guardrail gets worse.
- Reports per 1,000 impressions.
- Hides per 1,000 impressions.
- Average survey score for worth your time.
- Share of first-time posters who get at least one reply within a day.
- Ranking time at the 95th percentile, the time within which 95 out of 100 requests finish.
Here is the team's rollout plan for the new value model, from offline checks to a long-term holdout.
Offline checks
AUC and calibration for every head on last week's data. Stop here if any head gets worse.
Shadow scoring
Score live requests with the new model but keep showing the old ranking. This checks speed and errors without changing what anyone sees.
Small A/B test
Give 1% of users the new ranking for three days. Watch the guardrails daily for anything badly broken.
Full A/B test
Grow to 5% of users for two weeks, so weekday and weekend habits both show up. Decide using the goal metric and every guardrail.
Long-term holdout
After launch, keep 1% of users on the old ranking for three months. This shows effects that take weeks to appear, such as people quietly leaving.
What is a feedback loop in feed ranking and how do you break it?
A feedback loop happens because the model learns from reactions to posts it chose to show. Its own choices shape its next training data. Left alone, the feed keeps favouring what it already favours.
There are two loops. In the data loop, posts the ranker never shows never collect reactions, so it never learns they were good. In the preference loop, what people see slowly changes what they like.
The data loop: a ranker cannot learn about posts it never shows
Here is a small simulation of the data loop. There are 200 posts, each with a hidden real like rate. The old ranker only ever showed 10 of them, and every post the ranker has never shown scores 0.
Each of 5,000 sessions shows the 10 best-scoring posts. With exploration on, each slot has a 5% chance of showing a random post instead. Pause and predict: how many of the 10 truly best posts will each version find?
import numpy as np
def simulate(explore, seed, posts=200, slots=10, sessions=5000):
rng = np.random.default_rng(seed)
true_rate = rng.beta(2, 30, posts) # real like rate of each post, about 6% on average
shows, likes = np.zeros(posts), np.zeros(posts)
shows[:slots] = 50 # the old ranker only ever showed posts 0 to 9
likes[:slots] = rng.binomial(50, true_rate[:slots])
for _ in range(sessions):
score = np.divide(likes, shows, out=np.zeros(posts), where=shows > 0)
page = np.argsort(-score)[:slots] # unseen posts score 0, so they never win
explore_slots = rng.random(slots) < explore
page[explore_slots] = rng.integers(posts, size=explore_slots.sum())
np.add.at(shows, page, 1) # add.at counts a post twice if it fills two slots
np.add.at(likes, page, rng.random(slots) < true_rate[page])
top10 = np.argsort(-likes / np.maximum(shows, 1))[:slots]
best10 = np.argsort(-true_rate)[:slots]
return len(set(top10) & set(best10)), likes.sum() / shows.sum()
for explore in (0.0, 0.05):
runs = [simulate(explore, seed) for seed in range(5)]
print(f"explore {explore:.0%}: true top-10 posts found {[r[0] for r in runs]}, "
f"likes per 100 views {100 * np.mean([r[1] for r in runs]):.1f}")With numpy 2.5.4 on Python 3.13 it ran in a few seconds on our machine and printed this.
explore 0%: true top-10 posts found [0, 1, 1, 1, 0], likes per 100 views 5.5
explore 5%: true top-10 posts found [7, 7, 7, 7, 8], likes per 100 views 14.0What just happened? Without exploration, the ranker kept showing the posts it already had data for and found 0 or 1 of the best ten. With 5% random slots it found 7 or 8, and likes per 100 views rose from 5.5 to 14.0.
Scope this result carefully. Unseen posts scored 0 here, the harshest case. When we gave unseen posts an average starting score instead, the ranker without exploration found 0 to 4 of the best ten, and 5% exploration found 4 to 6.
The preference loop: what people see changes what they like
A 2019 paper on degenerate feedback loops modelled this second loop. Degenerate here means a user's interests drifting far from where they started, towards extremes.
In its simulations, a recommender that always served each user's current top interests degenerated faster than learning recommenders that explored or one that picked at random. The paper names continuous random exploration and a candidate pool that grows at least in step with time (linearly) as the best remedies.
It also adds a twist. A little random noise added to that accurate recommender sped degeneration up, and only larger noise slowed it down. So test the size of your exploration, not just whether it exists.
The diagram shows the loop and the team's two ways to add outside evidence.
The feedback loop and two ways to break it
Drag to exploreThe ranker trains on what it showed. Notice that exploration slots and the holdout group add evidence the ranker did not choose. Shares are made up.
Diagram connections:
- Ranker to Posts people see (Top picks)
- Exploration slots to Posts people see (Posts it did not pick)
- Posts people see to Logged actions
- Holdout group to Logged actions (Baseline behaviour)
- Logged actions to Training data
- Training data to Ranker (Nightly retraining)
- Ranker: Orders posts by value score
- Posts people see: Mostly the ranker's top picks
- Exploration slots: 5% of slots go to random posts
- Logged actions: Likes, hides, reports, survey answers
- Holdout group: A separate 1% sees a newest-first feed
- Training data: Each row keeps its chance of being shown
These habits keep the loop healthy:
- Explore on purpose. A small share of slots shows posts the ranker would have skipped, so new kinds of content get a fair chance.
- Log the chance of being shown. Store how likely each post was to be shown, so training can give extra weight to rare choices.
- Keep a holdout. A separate small group on a newest-first feed shows how people behave without the ranker's influence. This is not the rollout holdout, which stays on the old ranker.
- Keep the pool growing. Make sure new posts and new posters keep entering the candidate list every day.
How do you explain feed ranking in a system design interview?
Explain it as a pipeline with an explicit goal, then spend most of your time on what to predict, how to combine it and how to test it. The order below fits a 45-minute round.
Ask what good means
Clarify the goal beyond clicks, the harms to avoid, the scale and the time budget. Say plainly that engagement alone is not the goal.
Draw the stages
Candidate sources, an integrity filter, a light ranker, a heavy ranker, a value model and a re-ranker. Give rough post counts at each stage.
Define labels and heads
List the actions you predict, including negative ones like hide and report. Explain why one shared multi-task model helps rare labels, and when it can hurt.
Combine with a value model
Show the weighted sum, negative weights for harms and a wellbeing term from surveys. Say who owns the weights.
Handle bias and loops
Mention position bias, calibration, exploration slots, logging the chance of being shown and a holdout group.
Test with guardrails
Offline AUC and calibration, then an A/B test with a goal metric and named guardrails, then a long-term holdout.
Questions people ask
- What is the difference between feed ranking and recommendation?
- Feed ranking is one kind of recommendation, focused on ordering a stream of fresh posts for each person. General recommendation also covers products, videos or songs, where items last longer. Feeds add their own problems: posts can go stale within hours, the page must be varied, and anyone can post, so integrity matters more.
- Why not just show posts in newest-first order?
- Newest-first is simple and easy to explain, but in a busy feed it buries useful posts under a flood of minor ones. Some products offer it as an option, and it makes a good holdout baseline. Ranking helps when there are more posts than anyone can read.
- How are the weights in a value model chosen?
- Weights start as a product decision about how much each action is worth, then get tuned with experiments. Teams try a few weight sets in A/B tests and keep the one that improves the goal metric without hurting any guardrail. Write down why each weight exists, so later changes stay deliberate.
- What is a guardrail metric in feed ranking?
- A guardrail metric is a number that must not get worse when you ship a ranking change, even if the main goal improves. Common feed guardrails are reports and hides per 1,000 impressions, survey scores, reach for new posters and ranking latency at the 95th percentile.
- Do you need deep learning for feed ranking?
- Not always. A common starting point is gradient-boosted trees, many small decision trees where each new tree is trained to correct the errors left by the trees before it. Deep multi-task models help once you have lots of data and several actions to predict. The value model, guardrails and testing still decide whether the feed is good.
- How do you measure user wellbeing in a feed?
- You ask people directly and then predict their answers. A short survey, such as whether a post was worth their time, goes to a small random sample. A model learns to predict the answer for everyone, and that prediction becomes a term in the value model. Check that the people who answer look like your whole user base.
- How often should a feed ranking model be retrained?
- Often enough to keep up with new posts and habits, which for many feeds means daily. Each retrain should pass the same offline checks, including calibration, before going live. Frequent retraining also tightens the feedback loop, so keep exploration and a holdout running all the time.
Sources and further reading
- Engagement, User Satisfaction, and the Amplification of Divisive Content on Social Media (Milli et al., 2023), abstract
- Degenerate Feedback Loops in Recommender Systems (Jiang et al., 2019), full paper: simulations and conclusion
- An Overview of Multi-Task Learning in Deep Neural Networks (Ruder, 2017), Sections 3.1, 4 and 5.2
- Unbiased Learning-to-Rank with Biased Feedback (Joachims et al., 2016), abstract
- What are you optimizing for? Aligning Recommender Systems with Human Values (Stray et al., 2021), abstract
- Building Human Values into Recommender Systems: An Interdisciplinary Synthesis (Stray et al., 2022), abstract
- Trustworthy Online Controlled Experiments: Five Puzzling Outcomes Explained (Kohavi et al., KDD 2012), Sections 3.3 and 3.4.4