Markdown · llms.txt

How the X (Twitter) algorithm works in 2026

Last updated 2026-10-11. This page reads the public For You pipeline. X is the product name. Search still calls the same system the Twitter algorithm. It is not a growth guide and not a measurement of anyone’s impressions.

It follows X_ALGORITHM_BOOST_PLAYBOOK.md, checked against xai-org/x-algorithm commit cb45b55 (2026-10-09, “Open-source X Recommendation Algorithm”). The production weight mirror in home-mixer/params/param.rs is stamped last sync 2026-10-08T16:00:35Z. The dated commit list is X algorithm changes in 2026. A file-by-file map of the GitHub repo is Twitter algorithm on GitHub.

Where a number appears below, it is a published default in that tree. Experiments can override defaults per viewer. WeightPerturbationSigma defaults to 0.0.

What a For You request does

README.md and home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs build a request in this order:

  1. Query hydration. The viewer’s recent engagements (the model’s main input), follow list, blocks and mutes, muted keywords, posts already seen or served, and followed topics.
  2. Candidate sources, in parallel. In-network: Thunder. Out-of-network: Phoenix retrieval, SimClusters, and a popular-posts list that has been on since the 2026-10-07 param sync. Tweet Mixer, the SID source, and the Phoenix MoE source exist and default off.
  3. Hydration. Text, media, author, quote target, language, engagement counts, semantic id, and whether the author mutually follows the viewer.
  4. Pre-scoring filters. Duplicates, age, the viewer’s own posts, out-of-network replies and reposts, muted keywords, blocks, posts already seen or served, and the other filters below.
  5. Scoring. Phoenix predicts one value per action. A weighted sum turns those predictions into one number. When vm-ranker recomputes the sum, it applies author-diversity decay and an out-of-network factor. A cold-start lift can move a new post up.
  6. Selection. TopKScoreSelector keeps the top 50 (TOP_K_CANDIDATES_TO_SELECT in home-mixer/params/config.rs). The served page is smaller (RESULT_SIZE 35, plus modules).
  7. DPP reorder. vm-ranker runs a determinantal point process so neighboring posts are less similar (vm-ranker/dpp.rs). Defaults: enabled, theta 0.65, pool rank 150.
  8. Post-selection filters. Visibility filtering, then conversation dedup.

Visibility (drop, notice, interstitial, or allow) is a separate service, visibility-filtering/. The ranker does not decide it.

Where candidates come from

SourceDefaultWhat the code says
ThunderonRecent posts from accounts the viewer follows. Cap ThunderMaxResults 1200. Per author, the return caps in thunder/config.rs are 50 originals, 30 replies, and 100 videos.
Phoenix retrievalonTwo-tower retrieval over engagement history. PhoenixMaxResults is 1000. The cold-start retrieval cap is 200.
SimClustersonFavorite-graph clusters (LOG_FAV_BASED_TWEET). The source keeps 800; the ANN query cap is 200. Candidate age cap is 48 hours.
Popular postson since 2026-10-07A shared list. Cap 500. The README describes the initial list as posts from the most-followed active accounts.
Tweet Mixer, SID, Phoenix MoEoffPresent in the tree, not on by default.

The hard age cut for For You is AgeFilter at MAX_POST_AGE = 48 hours. A “Thunder keeps posts for two days” reading comes from a test constructor, not from that filter.

Filters that run before a score exists

From the README’s filtering section and home-mixer/filters/:

  • Older than 48 hours.
  • Reposts and replies from accounts the viewer does not follow (OONRetweetReplyFilter). EnablePhoenixOonReplies defaults false.
  • The viewer has blocked or muted the author.
  • Already seen. A bloom filter plus an explicit seen-id set. Recycling the same post id does not get a second impression.
  • The viewer’s muted keywords, including hashtag keywords.
  • Subscriber-only posts the viewer cannot access.
  • The viewer’s own posts (SelfTweetFilter).
  • A protected author’s post, when the viewer does not follow them (protected_author in visibility-filtering/rules/author_rules.rs). Followers can still be shown it. A protected account gets no out-of-network For You distribution.

After selection, conversation dedup (DedupConversationFilter) keeps one post per conversation id. The highest score wins, whichever post that is. A reply can beat its own thread starter.

How the number is computed

Phoenix emits a probability, or a continuous value such as dwell time, per head. compute_weighted_score in xai-value-model/scoring.rs is:

weighted = Σ (weight_i × prediction_i)

A weight multiplies that viewer’s predicted probability of the action (or a predicted duration). It does not multiply raw like or reply counts. The same comments say a report’s weight is large because a report is rare: the baseline probability of a report is more than 1000× lower than a like, so the coefficient has to be large for the prediction to move rank. “One report cancels N likes” is not a reading the code supports.

The published defaults, and the out-of-network and author-diversity multipliers, are on the weights page.

offset_score then shifts a negative weighted sum so it stays sortable (NEGATIVE_SCORES_OFFSET = 0.001). With the published default multiplier_pre_offset = false, author diversity and the out-of-network factor multiply after that offset.

What this tree does not contain

Trained Phoenix weights. The Grox classifier prompts (they are Jinja templates loaded by name, and the README says they are not in the repo). The numeric rule that turns slop_score or a safety label into a visibility decision. The experiment bucket a given viewer is actually in. A day-of-week posting constant.

The old quality gate is also gone. There is no 0.4 cutoff on the current Gemma screen. That screen parses an integer slop_score and stores it. No cutoff appears on that path.

Safety labels still exist. Grox PTOS categories in grox/flows/ptos/state.py are eleven: HateOrAbuse, ViolentSpeech, ChildSafety, IllegalAndRegulatedBehaviors, Spam, SuicideOrSelfHarm, AdultContent, ViolentMedia, TerrorismOrViolentExtremism, CivicIntegrity, AgeGatingHarmfulText. Spam subtypes include SpamEngagementFarming, SpamEngagementTrading, SpamHashTagAbuse, SpamScamLinks, SpamBotProduced, and SpamPlatformManipulation. The prompts that fire them are unpublished, so this page does not invent a threshold.

tweet-factory does not run this pipeline. How drafts are scored is a separate, local heuristic.

Changelog

The pipeline above is commit cb45b55. Older snapshots of this same repository changed defaults without changing the request shape. The short list, with dates from the playbook and the repo README:

DateWhat changed in the published tree
2026-07-24Mutual-follow reply boost settled at +15, after a test at +20 (docs/BIDIRECTIONAL_BOOST_CHANGE.md).
2026-08-13README release: published weights, visibility filtering, and Phoenix training code. The demonstration model was replaced.
2026-09-04e4dcedd dedupes in-network ids before a visibility-filtering lookup.
2026-09-29README: Brazil 2026 election account list updated. The filter drops reported accounts unless the viewer follows them.
2026-10-06e62790c moves the vm-ranker cluster default from Experiment6 to Experiment1.
2026-10-0778460ca sets PostUnexploredWeight from 0.02 to 0.015 and turns the popular-posts source on.
2026-10-0835650fb adds favorite-count hydration on the Phoenix index. Video carousel params ship default off. Param mirror stamp 2026-10-08T16:00:35Z.
2026-10-09cb45b55 changes ranker attention and sequence packing inside phoenix/xrex/. The param file bump is the sync timestamp.

The full notes are on X algorithm changes in 2026. A browser draft scorer, separate from this ranker, is tweetfactory.sh/score.

FAQ

How does the Twitter algorithm work in 2026?

Same pipeline as the X algorithm. At commit cb45b55 the For You request hydrates the viewer, pulls in-network posts from Thunder and out-of-network posts from Phoenix retrieval, SimClusters, and a popular-posts list, drops posts that fail age, social, seen, and reply filters, scores the rest as a weighted sum of predicted actions, keeps the top 50, reorders for diversity, then applies visibility filtering and conversation dedup.

How does the X algorithm work?

The open-source For You path, at commit cb45b55, hydrates the viewer, pulls candidates from Thunder (in network) and from Phoenix retrieval, SimClusters, and a popular-posts list (out of network), drops posts that fail age, social, seen, and reply filters, scores the rest as a weighted sum of predicted actions, keeps the top 50, reorders for diversity, then applies visibility filtering and conversation dedup.

Is the X algorithm open source explained by one file of weights?

The weight defaults are published in home-mixer/params/param.rs and duplicated, with one difference, in vm-ranker/params.rs. The ranker is the whole pipeline above. Trained model weights and the Grox prompts are not in the repo. A default of 0 means that head is off in the mirrored primary config, not that the head does not exist.

Does the X algorithm rank by raw like counts?

No. home-mixer/params/param.rs, xai-value-model/scoring.rs, and the README’s 2026-08-14 note say a weight multiplies a predicted probability or a predicted duration. favorite’s published coefficient is 0.5. Copy-link share is 20.0, reply is 5.0, and quote is 5.0. Those are coefficients on probabilities, not “one reply equals ten likes.”