How the X algorithm works

Straight from X's open-source code on GitHub, in plain English.
In one sentence: X guesses, for every post it could show you, how likely you are to like it, reply, share it, read it, or mute the author, then adds those guesses up with fixed weights and shows the highest totals first.
This page is built only from X's own published code and READMEs on GitHub. Every number links to the file it came from. Anything I could not confirm in the code is marked uncertain.
1. The simple version
Think of the For You feed as a store that restocks a shelf just for you, every time you open the app.
- Gather. It grabs a pile of recent posts: some from people you follow, some from people you don't.
- Throw out. It removes posts you've seen, posts older than 48 hours, posts from accounts you block or mute, and posts matching your muted words.
- Guess. A model looks at what you recently did on X and predicts how likely you are to take each action on each post.
- Add up. Those predictions are multiplied by weights and summed into one score.
- Tidy. It spreads out repeated authors, discounts posts from strangers a bit, gives small new accounts a lift, and avoids showing near-identical posts side by side.
- Check. A separate safety system decides whether each post may be shown at all.
Source: xai-org/x-algorithm README (Overview, How It Works, Filtering).
2. How a feed is built (diagram)
Source: README: System Architecture, Components, pipeline in phoenix_candidate_pipeline.rs, filters in home-mixer/filters/.
The parts, one line each
- Home Mixer
- Builds the feed: pipeline stages, scoring weights, calls to other systems.
- Thunder (in-network)
- Holds recent posts in memory and returns those from accounts you follow.
- Phoenix retrieval (out-of-network)
- Turns you and every post into vectors and returns posts closest to you.
- SimClusters (out-of-network)
- Groups accounts and posts by who engages with what, then uses those groups to find posts.
- Popular posts
- A shared list of popular recent posts, initially from the most-followed active accounts.
- Phoenix ranking
- The transformer that predicts each action. Training and serving code in JAX and Rust.
- VMRanker
- Reorders with a determinantal point process: gives up a little score for less similarity between neighbors.
- Visibility filtering
- Decides show, drop, or show behind a warning, using your blocks/mutes and labels from systems like Grox, agatha, user-cred-v2 and botmaker rules.
3. The engagement weights (exact values)
Current defaults in home-mixer/params/param.rs (lines 396–514 at commit 5ed7963). The arithmetic is in xai-value-model/scoring.rs.
- Positive signal (2026)Weight
- Share via copy link+20.0
- Reply+5.0
- Quote+5.0
- Share via DM+5.0
- Follow author+4.0
- Share+2.0
- Repost+1.0
- Favorite (like)+0.66
- Click dwell time (continuous)+0.4
- Click+0.3
- Open link+0.2
- Photo expand+0.05
- Dwell+0.05
- Quoted post click+0.05
- Video open+0.02
- Post unexplored+0.015
- Dwell time (continuous)+0.006
- Profile click0.0
- Video quality view0.0
- Quoted video quality view0.0
- React with video0.0
- Negative signal (2026)Weight
- Report−234.0
- Mute author−58.8
- Not interested−52.272
- Block author−31.2
- Not dwelled−0.02
Also in that file: BidirectionalFollowReplyWeightBoost = 15.0 and BidirectionalFollowDwellWeightBoost = 0.0. The names point to an extra reply weight when you and the author follow each other; I did not trace exactly how it is applied uncertain.
Read this before quoting the numbers. The weights multiply the predicted probability that you take an action, not raw counts. X's own comment: the baseline chance of a report is "more than 1000x lower than a Like", so it gets a big weight just to matter at all. "One report cancels 468 likes" is explicitly called incorrect in the README and in param.rs.
Note: the README's "468 times" example matches a like weight of 0.5 (234 ÷ 0.5). The current file says 0.66, which gives about 355×. The example may predate a change uncertain.
4. What changed over time
Dates come from GitHub commit dates, README update notes, and repo creation dates.
| Date | What happened | Source |
|---|---|---|
| Mar 27, 2023 | twitter/the-algorithm repo created: Scala/Java services, SimClusters, TwHIN, RealGraph, Earlybird light ranker, heavy ranker. | repo |
| Apr 5, 2023 | Heavy ranker weights published (reply 13.5, reply engaged by author 75, report −369 …). | recap README |
| Apr–May 2023 | More parts open-sourced: Representation Manager/Scorer (Apr 28), Tweetypie and pushservice (May 19). | commits |
| Jul 13, 2023 | "Update home mixer with latest changes". | commit |
| Sep 3, 2025 | Last commit on the old repo: "update for-you recommendations code". | commit |
| Jan 20, 2026 | New repo xai-org/x-algorithm: Rust home-mixer, Thunder, Phoenix. Phoenix shipped as a sample transformer ported from Grok-1. | phoenix/README.md |
| May 15, 2026 | Update commit (message only: "Open-source X Recommendation Algorithm"); details not listed uncertain. | commits |
| Aug 13, 2026 | Big release: weights and config, visibility filtering and label systems, real Phoenix training code (replacing the demo), SimClusters added. | README Notable Updates |
| Aug 14, 2026 | Comments added explaining that weights scale probabilities, not counts. Brazil election filter added. | README |
| Sep 18, 2026 | Under the Hood reports show legal withholding by country. | README |
| Oct 8, 2026 | Ranking predicts time spent much better. | loss_recsys.py |
| Oct 13, 2026 | Retrieval also trained to surface posts people read all the way through. | two-tower model |
| Oct 26, 2026 | Brazil 2026 election filter removed. | README |
What changed, and what it means
| Then (2023) | Now (2026) | What it means |
|---|---|---|
| Many Scala/Java services; Earlybird light ranker then MaskNet heavy ranker on hand-built features | Rust home-mixer + one transformer (Phoenix) that reads your recent action history | Your own recent behavior is the main input, not hand-built features. |
| 10 predicted actions | ~25 actions incl. shares, DM, copy link, dwell time, follow, mute, block | Shares and time spent are now explicit signals. |
| Reply 13.5; reply engaged by author 75 | Reply 5.0; no "engaged by author" weight in param.rs; mutual-follow reply boost 15.0 | Replies still count far more than likes, but the famous "75" is gone from the published weights. |
| Like 0.5 | Like 0.66 | Likes are still the weakest of the main signals. |
| Negative feedback −74; report −369 | Not interested −52.272, mute −58.8, block −31.2, report −234 | Negatives are split out and still dominate when they're likely. |
| Search index gave ~50% of posts (in-network) | Thunder (in-network) + Phoenix retrieval + SimClusters + popular posts | No published 50/50 split anymore uncertain. |
| Grok: not involved | Earlier xai release: sample transformer ported from Grok-1. Aug 2026: production code shipped instead | "The feed is Grok" overstates it. The code shows a transformer recommender, not a chatbot. Grox (LLM prompts, not published) labels content uncertain. |
5. The 2023 system in brief
From the twitter/the-algorithm README:
- Candidate sourcing
- In-network from the search index (Earlybird), "~50% of posts". Out-of-network via tweet-mixer, UTEG (GraphJet interaction graph) and follow-recommendation-service.
- SimClusters
- "Community detection and sparse embeddings into those communities." README
- TwHIN
- "Dense knowledge graph embeddings for Users and Posts." README
- RealGraph
- Predicts how likely one user is to interact with another. README
- Tweepcred
- PageRank-based user reputation (today's counterpart: user-cred-v2).
- Light ranker
- Used by the search index (Earlybird) to pre-rank posts.
- Heavy ranker
- Parallel MaskNet that outputs engagement probabilities, combined with the weights below. recap README
- Mixing and filtering
- home-mixer (built on product-mixer) builds the timeline; visibility-filters handle legal, quality and safety filtering.
- Heavy ranker weight (Apr 5, 2023)Weight
- Reply engaged by author+75.0
- Reply+13.5
- Good profile click+12.0
- Good click+11.0
- Good click v2 (2+ min in conversation)+10.0
- Retweet+1.0
- Favorite (like)+0.5
- Video playback 50%+0.005
- Negative (Apr 5, 2023)Weight
- Negative feedback v2−74.0
- Report−369.0
6. What it means for posting and replying
These follow from the code. The size of any effect on your account isn't published.
- Write for replies, quotes and shares, not likes. Reply, quote and DM share are 5.0, copy link 20.0, like 0.66. See Reply on X and How to Reply.
- Earn the read. Dwell, dwell time and click dwell time are scored, and the Oct 2026 updates target time spent and reading all the way through. A strong first line matters: Hooks on X.
- Avoid "not interested", mutes and reports. Bait that annoys people can cost more than it earns. → Negative signals
- Freshness matters. Posts older than 48 hours are filtered out of For You. → Timing
- Media is scored lightly. Photo expand 0.05, video open 0.02. → Media and video
- Shares are the top positive weights. Copy link 20, DM 5, share 2. → Shares on X · Share Hooks
- Follows and mutual follows count. Follow author 4.0, plus a mutual-follow reply boost. → Growing followers
- Replies from strangers don't travel out-of-network.
OONRetweetReplyFilterremoves reposts and replies from accounts the viewer doesn't follow. Your reply mainly reaches your followers and the people in that thread.
7. Myths vs facts
| Myth | What the code says |
|---|---|
| "One report cancels 468 likes." | False, per X's own README and code comments: weights scale predicted probabilities, not counts. |
| "A reply is worth 75 likes." | That came from 2023 (reply engaged by author 75 vs like 0.5). It's not in the 2026 param.rs, and it was never a count conversion. |
| "Grok picks your feed." | Overstated. Phoenix is a transformer recommender; an earlier sample was ported from Grok-1. Grox uses LLM prompts for labeling, and those prompts aren't published uncertain. |
| "Links are banned or penalized." | Open link has a positive weight (0.2). No link penalty appears in param.rs. Other effects elsewhere aren't ruled out uncertain. |
| "Paying for Premium is a ranking weight." | No subscription weight appears in param.rs. IneligibleSubscriptionFilter only hides subscriber-only posts. Other boosts elsewhere aren't ruled out uncertain. |
| "Old posts can go viral in For You days later." | AgeFilter removes posts older than 48 hours from For You. |
| "Everyone sees the same ranking." | No. Predictions are personal: they're driven by each viewer's own action history. |
8. Glossary
- In-network / out-of-network (OON)
- Posts from accounts you follow / accounts you don't.
- Candidate
- A post that might be shown, before ranking.
- Retrieval
- Finding candidates, e.g. nearest vectors in Phoenix's two-tower model.
- Ranker
- The model that scores candidates.
- Weight
- A multiplier on a predicted probability.
- Dwell
- Time spent on a post.
- Embedding
- A list of numbers that represents a user or post so similar ones sit close together.
- SimClusters
- Communities of accounts and posts found from engagement.
- TwHIN
- 2023 graph embeddings for users and posts.
- RealGraph
- 2023 model of how likely two users are to interact.
- Light / heavy ranker
- 2023 fast pre-ranker / full neural ranker.
- Visibility filtering
- Decides whether a post can be shown at all.
- Under the Hood
- X's tool that shows the visibility labels on your own account and posts.
9. FAQ
- Is this really the production code?
- The README says it's the core code for For You. Some files are withheld (Grox prompts, some botmaker rules). Production values may be changed through configuration, so live values can differ uncertain.
- Are the weights fixed?
- They're defaults declared as params, and experiments can override them ("Experiments and Configuration" in the README).
- Does this cover Following, Search or notifications?
- The new repo covers For You. The 2023 repo also covered Recommended Notifications.
- Can I check whether my account is limited?
- Yes. The README describes Under the Hood reports for your account and posts.
- How much does a reply boost my reach?
- Not published. The weight applies to a viewer's predicted chance of replying, not to your counts.
10. Sources
- xai-org/x-algorithm README.md (commit 5ed7963, Oct 28, 2026)
- home-mixer/params/param.rs: weights, cold-start params
- xai-value-model/scoring.rs
- phoenix/README.md (Grok-1 note)
- home-mixer/filters/
- twitter/the-algorithm README.md
- twitter/the-algorithm-ml projects/home/recap/README.md: 2023 weights
- SimClusters README, TwHIN README, RealGraph README
Not published as numbers in param.rs: the exact author-diversity decay and floor, and the out-of-network discount factor. I left them out instead of guessing.