X cold start: new readers, low-view posts and score lifts | Gyo
What cold start means in X’s recommendation code
A new reader and a low-exposure post pose different problems. X’s code has separate routing, filtering and candidate-lift mechanisms for them.
Gyo
“The algorithm does not know me yet” can describe two very different problems. A reader has little history to personalize a feed. Or a post has received too little exposure to reveal much about its response.
X’s published code handles these through separate mechanisms: history-based routing, conditional rules for new or returning viewers, retrieval categories and a candidate-level cold-start adjustment. None establishes a fixed starting audience for every post. The useful details are in the conditions.
Several names in the repository contain “new user” or “cold start.” They do not all check the same person, clock or data source.
Mechanism
Whose information matters
Retrieval/ranker short-history routing
The reader’s aggregated action-sequence length
New-user engagement filter
The reader’s account age or return window, plus candidate metrics
FAQ
Does every new X post get 200 test impressions?
The local author cold-start helper uses a below-200 Home-view eligibility cutoff in this snapshot. It does not grant 200 impressions. Retrieval, other eligibility conditions, experiment assignments, candidate choice and later processing still apply.
Does cold start always mean a new account?
No. These mechanisms use different inputs: reader sequence length, viewer account age or return time, and candidate age, author followers or Home views. A low-exposure candidate can be considered for an established reader.
Does a cold-start lift guarantee the sixteenth feed position?
No. With the published target interval and enough candidates, the local helper uses the sixteenth sorted score as a floor for one chosen candidate. Ties, remote ranking and subsequent filters mean that is not a guaranteed final screen position.
Does X randomly promote every eligible low-view post?
No. The helper can select by original score or use a Beta-sampling shortlist followed by an original-score comparison. It considers candidates already in its input, and at most one chosen candidate gets the local score-floor application.
New-user soft-NSFW filter
The reader’s age and scoring-history length, plus candidate flags
Author cold-start adjustment
Candidate age, author followers, Home views, current scores and experiment assignments
A new reader can receive old authors’ posts. An established reader can receive a recently published post from a small author. An old account can have little usable sequence history. Keeping those cases separate prevents a lot of advice from being attached to the wrong condition.
The clocks differ too. Account age can be derived from the viewer ID, a return window uses a timestamp on the query, and post age uses the candidate’s ID. One threshold cannot stand in for all three.
A short action history can choose another model route
PhoenixSource::resolve_cluster reads the retrieval sequence’s metadata length. If a configured history threshold is greater than zero and the action count falls below it, the source selects the configured new-user retrieval cluster. An absent length is treated as zero for this branch.
The prediction scorer has a parallel ranker-routing check, using the scoring sequence rather than the retrieval sequence. These are separate settings for separate stages, not one universal “new account” classifier.
Both history thresholds default to zero in this snapshot. A zero threshold disables this particular short-history branch. The existence of a differently named cluster in configuration does not prove that all new readers are routed to it.
For the reader, the implication is straightforward: there is code for choosing a different route when usable history is limited. What that route predicts, and whether it improves the experience, depends on the selected model and data. The caller does not expose those outcomes by naming a cluster.
Cold retrieval categories are not promised impressions
Part three showed that general Phoenix retrieval can request a cold-start result allowance and receive distinct dataset categories. Its response mapping gives HomeCold and ZeroFav candidates different served types.
Those names identify returned categories. They do not establish that every unseen post is indexed into one, retrieved for a certain number of readers, or guaranteed to survive ranking and visibility checks. The result allowance is a request parameter, not a per-author exposure balance.
That distinction becomes even more important when we find the number 200 elsewhere. Two constants can share a value while controlling entirely different parts of the system. We have to follow the consumer before giving the number a meaning.
Some new-reader checks can remove candidates
Cold-start handling is not always a boost. NewUserMinEngagementFilter activates only when its switch is on and the viewer falls within an account-age or return window.
It can examine favorites, an engagement sum or views, with an optional ratio mode for the relevant metrics. Candidates explicitly marked out-of-network are compared with the configured threshold. Candidates whose in-network state is not explicitly false are kept by this helper. Missing metrics are also kept; if no candidate has the chosen metric, the filter returns the whole input unchanged.
The published defaults disable this filter. Its 1,800-second age and return windows are therefore not evidence that every new reader gets a mandatory thirty-minute filter period.
The separate NewUserSoftNsfwFilter checks for a For You request without topics, an enabled switch, viewer account age below a limit and a scoring-sequence length below its configured bound. When active, it removes candidates explicitly marked both out-of-network and soft-NSFW. Unknown flags are not the same as affirmative flags in that predicate.
Its snapshot default is also disabled. The public age and history settings describe what the function would check when activated; they do not establish its live coverage.
These examples show why “new users get a boost” is an incomplete description. A new reader’s request can take a different prediction route or apply an extra eligibility check. Neither is an account-growth entitlement for a new author.
The author adjustment starts with candidates already scored
The more direct exposure mechanism is AuthorColdStart. Despite the EnableViewerColdStart switch name, its candidate eligibility does not require the viewer’s account to be new.
In VMRanker::local_scores, the caller prepares weighted values and passes candidates and those values to this adjustment. We are downstream of retrieval and pre-scoring filters. The helper cannot lift a post absent from its input list.
The adjustment exits unchanged on topic requests. It then reads its enable setting, target-slot settings, eligibility limits, sampling parameters and viewer experiment arm. When the switch is off or no target can be selected, it returns the original scores.
The viewer arm comes from treatment/control flags. In this implementation, treatment takes precedence if both flags are set; neither means holdout. Control and treatment arms require the corresponding author corpus, resolved through author feature rules. Holdout accepts any author corpus for this particular eligibility test. The name “holdout” should not be used to assume the entire function skips that arm—the code does not do that.
What a candidate must satisfy
The eligibility predicate combines several conditions. A candidate must pass the base author/post check, the experiment-corpus check, the age check, a relative-position check and the Home-view check.
Not a reply and not a repost under the checked fields
Available author follower count
At most 50,000
Post age
At most 7,200 seconds, or two hours
Available Home-view count
Below 200
Position among nonzero scores
Below a cutoff derived from 97% of that count
Missing follower and Home-view counts fail their respective is_some_and checks. Missing is not treated as zero to make the candidate eligible.
The position calculation is quite specific. It ranks nonzero scores, computes an integer cutoff from the configured ratio and their count, then compares zero-based positions against that cutoff. A zero score gets no qualifying position from this helper. This is not a blanket invitation for every low-scoring candidate to leap into the feed.
The counts also need their correct names. The engagement-count hydrator keeps view_count and view_count_on_home separately. This eligibility check uses the latter. A public screenshot of a view count does not establish the exact internal Home count at evaluation time.
Two hundred is a strict cutoff on that input. It does not mean the system grants 200 impressions, stops all distribution at 200, or owes an under-threshold post the difference. The remaining conditions still have to hold, and only a candidate already present can be considered.
The lift uses a target score, not a guaranteed slot
The helper first chooses a target by sorting the input scores and sampling a rank from a configured half-open interval. With slot_min = 15 and slot_max = 16, a sufficiently large list yields zero-based rank 15: the sixteenth score.
If there are too few scores to leave a nonempty clipped interval, there is no target. The default does not reserve a sixteenth item in a response that never had enough candidates to begin with.
After choosing one eligible candidate, the application step sets its effective score to the greater of its original score and the target. The other scores are left alone. This can record a selected candidate even when its original score already meets the target; the bookkeeping is not proof of a positive numerical increase.
For an invented example, let the sorted scores be 20, 19, down to 1. The default target rank has score 5. If the chosen eligible candidate had score 3, this step raises it to 5. If it had score 6, it stays at 6. Equal scores, later ranking work and subsequent filters mean we should not translate that into a guaranteed final sixteenth position.
The outcome also records lift-to-rank metadata. The VM Ranker request builder passes that field and the locally prepared score into the service request. As part five explained, returned service scores can replace local values, while fallback paths retain local results. The local helper is one part of the final ranking path.
Exploration here is more specific than random promotion
When Thompson sampling is disabled, the helper chooses the highest original score among eligible candidates. With it enabled, pick_thompson samples a reward value for each eligible candidate, keeps up to a configured number with the highest samples, then chooses the highest original score within that short list.
The default shortlist size is two. So the algorithm is not simply “draw once and boost the candidate with the largest random value.” A candidate can make the sampled shortlist and still lose the final original-score comparison.
The sampler builds Beta parameters from prior values, scaled Home views and a nonnegative, capped favorite count. With the published prior parameters 0.75 and 49.25, a candidate with zero views and zero favorites starts with a Beta mean of 0.75 / 50 = 1.5%. With 100 scaled Home views and zero favorites, the mean becomes 0.75 / 150 = 0.5%.
Those means illustrate the distribution parameters; they are not the random draws, guaranteed selection chances, or measured click-through rates. The sampler uses favorite and Home-view fields from its inputs, and the code alone does not establish that their populations are a clean causal experiment.
Invalid sampling settings have a fallback to score-based selection, and a failed Beta construction returns a fixed sample value. These details matter when reproducing behavior. They are not something an author can reliably control by changing the wording of a post.
A cold-start choice still has to survive the feed
The adjustment changes a score for at most one chosen candidate in this local application. It does not insert an unlimited set of new posts, generate missing candidates, erase viewer history, remove a visibility label or skip post-selection checks.
A post that remains below 200 Home views is therefore not evidence, by itself, that a cold-start promise was broken. There is no such promise in this helper. We would need to know whether the request enabled it, which experiment assignments applied, whether the candidate qualified and whether it was chosen.
For a reader with little history, the relevant questions are different: which sequence was available, which cluster branch ran, and which new-viewer checks were enabled? Trying to answer those with an author’s follower count would mix the two problems again.
What the extra mechanisms actually tell us
Cold start is a collection of responses to missing or limited evidence, spread across a larger system. Some branches choose a different model route. Some conditionally filter what a new reader receives. One local ranking helper can raise a qualifying candidate’s score using an exploration procedure.
The source is specific enough to reject the idea of a universal starter batch, yet concrete enough to show that limited-exposure candidates are not handled only by ordinary weighted ranking. Both observations matter.
For authors, the useful takeaway is to ask which mechanism a claim describes. “New account,” “new reader,” “new post,” “zero favorites” and “low Home views” are five different descriptions. A threshold from one does not become a rule for the others just because all are discussed under cold start.
Source and verification notes
Source-checked on November 3, 2026, against revision b220448, then upstream HEAD. This article covers the cited callers, routing checks, viewer filters and local author cold-start helper. Published defaults are not a full description of feature matching or live experiment assignments.
The relative-position helper and base-eligibility examples were checked with isolated extracts of the published functions. The half-open target interval, score-floor example and Beta means were checked separately. This work does not estimate production selection probabilities, run a live audience experiment or verify the accuracy of the underlying counts.