Open source · read from the source

X's algorithm, read from the source

On 13 August 2026, X published the numeric ranking weights it had withheld in January. Most of the figures circulating about “the X algorithm” are wrong — usually because they were right about the 2023 model, which no longer exists. Every number on this page is a link to the line of source it came from, pinned to one commit.

Repository xai-org/x-algorithmCommit b089ce6 (2026-08-17)License Apache-2.0Parameters synced 2026-08-12T04:09:22Z

190

live parameters

changeable without a deploy

24

compiled constants

need a code change

123

pipeline components

sources, filters, scorers

10

claims checked

each against its source line

The weights

What each action is actually worth

X states it runs cron scripts that set the defaults in the repository's code to be the primary production values, and aims for experiments running at 10% or more of traffic to be visible in the repository. The values below are those defaults, read at the pinned commit.

ActionWeightvs a likeSource
binaryMultiplies the predicted probability of a discrete action.
share via copy linkShareViaCopyLinkWeight2040×param.rs
quoteQuoteWeight510×param.rs
replyReplyWeight510×param.rs
share via dmShareViaDmWeight510×param.rs
follow authorFollowAuthorWeight4param.rs
shareShareWeight2param.rs
retweetRetweetWeight1param.rs
favoriteFavoriteWeight0.5param.rs
clickClickWeight0.40.8×param.rs
open linkOpenLinkWeight0.20.4×param.rs
photo expandPhotoExpandWeight0.050.1×param.rs
quoted clickQuotedClickWeight0.050.1×param.rs
video openVideoOpenWeight0.050.1×param.rs
vqvVqvWeight0.050.1×param.rs
post unexploredPostUnexploredWeight0.02param.rs
dwellDwellWeight0param.rs
profile clickProfileClickWeight0param.rs
quoted vqvQuotedVqvWeight0param.rs
not dwelledNotDwelledWeight-0.02−0×param.rs
block authorBlockAuthorWeight-31.2−62×param.rs
not interestedNotInterestedWeight-43.2−86×param.rs
mute authorMuteAuthorWeight-58.8−118×param.rs
reportReportWeight-234−468×param.rs
continuousApplies to a quantity (watch or dwell seconds), not a probability.
cont dwell timeContDwellTimeWeight0.004param.rs
cont active secs 5m residual normContActiveSecs5mResidualNormWeight0param.rs
cont click dwell timeContClickDwellTimeWeight0param.rs
modifierNot a head weight: adds to another weight, or gates a branch.
bidirectional follow reply weight boostBidirectionalFollowReplyWeightBoost15param.rs
post unexplored in network onlyPostUnexploredWeightInNetworkOnlytrueparam.rs
bidirectional follow dwell weight boostBidirectionalFollowDwellWeightBoost0param.rs

Grouping into binary, continuous and modifier is oursthe ScoringWeights struct and each field's use in ranking_scorer.rs. X does not publish that taxonomy; we separate them because only the binary ones are comparable to each other.

Set a predicted probability for each action and watch its contribution to the score. Only the weights that multiply a probability are offered here — that is the arithmetic the code actually performs.

0% → 0.000
0% → 0.000
0% → 0.000
0% → 0.000
0% → 0.000
0% → 0.000
0% → 0.000
0% → 0.000
Weighted sum0.000

Why there is no “likes equivalent” here: Weights multiply a predicted probability, not an engagement count. Dividing one weight by another does not yield an exchange rate between actions.

Claim check

Numbers everyone repeats, checked against the code

These are not inventions. Most were accurate figures for the heavy ranker Twitter published in 2023, a Scala pipeline that has since been replaced. They kept circulating after the thing they described stopped existing.

Contradicted by the source

A repost is worth 20 times a like.

RetweetWeight is 1.0 and FavoriteWeight is 0.5, so a repost carries twice the weight of a like — not twenty times.

Where it comes from: No published version of the algorithm ever used 20. The 2023 heavy ranker also weighted retweet at 1.0 against favourite at 0.5.

Was true, of an older version

A reply is worth 27 times a like (or 13.5 times).

ReplyWeight is 5.0 against FavoriteWeight 0.5, so ten times — and forty times between mutual follows, because BidirectionalFollowReplyWeightBoost adds 15.0 to the reply weight for original posts between accounts that follow each other.

Where it comes from: Both figures were real, for a model that no longer exists: the 2023 heavy ranker published 27 on 2023-03-31, then 13.5 on 2023-04-05. They describe a Scala pipeline replaced by the current Rust one.

Was true, of an older version

Clicks on your profile are worth 12 times a like.

ProfileClickWeight is 0.0. A profile click contributes nothing to the weighted score.

Where it comes from: 12.0 was the 2023 weight for `good_profile_click` — a different, compound signal (opening a profile AND then liking or replying). The current model has a plain profile-click head, weighted zero.

No such parameter exists

A bookmark is worth 10 likes — bookmarks are the strongest signal.

There is no bookmark weight in param.rs, so bookmarks do not enter the weighted score at all. They are not, however, invisible: bookmark_count is hydrated onto every candidate as a model feature, and ClientTweetBookmark appears in the value-model gate. Read, but unweighted.

Where it comes from: The 2025 Scala refresh did declare a home_mixer_model_weight_bookmark parameter — with a default of 0.0. No published version ever weighted it at 10.

Right numbers, wrong reading

One report cancels 468 likes (−234.0 ÷ 0.5).

The arithmetic is right and the conclusion is still wrong. Weights multiply a PREDICTED PROBABILITY, not a count of actions. X states the baseline probability of a report is more than a thousand times lower than that of a like, so dividing one weight by another does not give an exchange rate between actions.

Where it comes from: This one is not stale — it is a misreading of correct numbers, and it appears even on pages that publish the right table. X added an explicit warning about it to its own README on 2026-08-14.

No such parameter exists

Engagement velocity counts 1000×, author authority 50×, recency 22×.

No parameter named for velocity, authority or recency exists in param.rs. Age is not a weight at all — it is a hard cut: AgeFilter drops any post older than MAX_POST_AGE, a compiled constant of 48 hours. Nothing multiplies a post's score by its freshness.

Contradicted by the source

A coordinated group can bury your post by mass-reporting or mass-blocking it.

X addresses this directly in the comments of param.rs, and the mechanism it describes is checkable: the model predicts YOUR likelihood of an action, so recommendations are personalised — reports from a brigade mostly affect what gets recommended to people similar to that brigade. And an engagement only counts if it happens on a post served in the Home Timeline: navigating straight to a post, for instance from a group chat, has no ranking impact.

Where it comes from: A reasonable inference from the very large negative weights, which the weights alone do not support.

Was true, of an older version

X published the code but withheld the ranking weights for security reasons.

True of the January 2026 release, false since 2026-08-13. The numeric defaults are now in param.rs, and X states cron scripts keep them equal to the primary production values.

Where it comes from: Accurate reporting of the January 2026 drop, never updated after August.

Contradicted by the source

Posts containing external links are downranked.

In the published ranking code OpenLinkWeight is POSITIVE at 0.2 and applied unconditionally — opening a link is rewarded. Links are penalised only through safety labels such as MALICIOUS_URL and DO_NOT_AMPLIFY, which are about the destination, not about linking out.

Contradicted by the source

A paid checkmark buys a ranking boost.

No premium, verified or subscription multiplier exists in param.rs, and no such rescorer appears in the published scorers. The 2023 code did carry one — multipliers of 4.0 in-network and 2.0 out-of-network for Blue Verified authors — and it is gone from the current tree. Honest limit: Phoenix is a learned model whose weights are not published, so a learned correlation cannot be excluded by reading the code.

Where it comes from: The 2023 Scala pipeline really did apply a 4.0 / 2.0 Blue Verified multiplier.

The pipeline

What happens to a post, in order

Candidate sources produce posts, hydrators attach features, filters can delete a post outright, scorers can only move it. Each node links to its file. Edges declare how we derived them — read from the code, given by the directory layout, or, at their weakest, matched by name.

Method and limits

What this page cannot tell you

The model is not the code

The weights above are applied to probabilities produced by Phoenix, a learned transformer whose trained parameters are not published. Reading the code cannot rule out a correlation the model learned on its own.

Some things are withheld

X states it holds back the Grox LLM prompt templates and some enforcement rules, to reduce gaming. The classifier code and the rule engine are published; the prompt text is not.

Nobody can verify what runs

X says cron scripts keep these defaults equal to production values, and that experiments above roughly 10% of traffic should be visible here. Both are claims about a system nobody outside X can observe.

Parameter names, code excerpts and the claim checks are kept in English on purpose: they quote source code, and a translated refutation stops being checkable against the line it cites.

Why a data company built this

This is the method we sell, applied to a source everyone argues about: take something opaque, turn it into a graph where every value carries the line it came from, and refuse to publish a number we cannot cite. We do the same for public procurement, research funding and company data.