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:22ZPage data regenerated 2026-08-18Checked against the repository every day

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

668

accounts named in the code

removed from For You unless you follow them

Check a post against the code

Paste a link to any public post. You get the rules that actually apply to it — including the country restrictions that can hide it — read from the pinned commit.

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.

Every row carries the code it was read from — pressExplainto unfold the actual lines of Rust, without leaving the page.

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 authorFollowAuthorWeight4
param.rs
shareShareWeight2
param.rs
retweetRetweetWeight1
param.rs
favoriteFavoriteWeight0.5
param.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.02
param.rs
dwellDwellWeight0
param.rs
profile clickProfileClickWeight0
param.rs
quoted vqvQuotedVqvWeight0
param.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.004
param.rs
cont active secs 5m residual normContActiveSecs5mResidualNormWeight0
param.rs
cont click dwell timeContClickDwellTimeWeight0
param.rs
modifierNot a head weight: adds to another weight, or gates a branch.
bidirectional follow reply weight boostBidirectionalFollowReplyWeightBoost15
param.rs
post unexplored in network onlyPostUnexploredWeightInNetworkOnlytrue
param.rs
bidirectional follow dwell weight boostBidirectionalFollowDwellWeightBoost0
param.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.

By country

What changes depending on where you read from

Two lists of countries are written directly into the code, and they do not mean the same thing. One withholds sensitive media from viewers who have not stated an age. The other simply decides which countries the model is allowed to tell apart — every other country becomes “other”, which is not a restriction, only a blind spot.

Click a country in rose to read the accounts this code names there, one by one. In the whole repository, exactly one country has such a list.

Brazil — 665 accounts named in the code
Brazil 2026 election filter Application providers that use a recommendation system for users must exclude from the results the channels and profiles reported to the Electoral Court under the terms of § 1º of this article and, except in cases of paid boosting, the content posted on them. https://dadosabertos.tse.jus.br/dataset/candidatos-2026 User ids below are obfuscated; usernames are included for transparency.
665
accounts written into the source, by id and by handle
unless you follow
their posts, reposts, quotes and thread ancestors are removed from For You — unless the viewer already follows the account
no country test
no country, market or locale condition appears in the filter or where it is registered

No country, market or locale condition appears in the filter file or around the line that registers it. That is a statement about the published code — which pipeline serves which market may be decided in a layer X does not publish.

Registered in the pipeline at home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs:368

  • @renildo
  • @renatoroseno
  • @pedro_lupion
  • @Sen_Cristovam
  • @marcelvanhattem
  • @nilvanferreira
  • @RafaellMilas
  • @chagasvieira
  • @GabrielSouza_RS
  • @Pimenta13Br
  • @rigotto
  • @euserafimcorrea
  • @ManuelaDavila
  • @CintyaMuniz
  • @depguibismarck
  • @cirogomes
  • @aldenorlima
  • @jooliveirapb
  • @caduxavier
  • @NetoAM
  • @marciokieller
  • @AlicePortugal
  • @eniobritodesa
  • @dep_geraldo
  • @inacioarruda
  • @murilogaldinopb
  • @FlavioBolsonaro
  • @BetoAlbuquerque
  • @alexandrekalil
  • @jessicamichels
  • @lcbusato
  • @Alice_Portugal
  • @DepArthurMaia
  • @kruke1
  • @marcelorangel1
  • @perpetua_acre
  • @PedroTaquesMT
  • @betinhogomes
  • @DanielVilela15
  • @zeca_dirceu
  • @eduardopaes
  • @RicardoBarrosPP
  • @danielxdonizet
  • @anyortiz
  • @priscilakrause
  • @advcorrea
  • @afranioboppre50
  • @DeputadoBacelar
  • @JuniorMochi
  • @GuilhermePaz

615 more accounts are in this list

Leave an email to open the full list here, and we will tell you when it changes — the daily watch already compares our pinned commit to theirs.

To be clear: this list is public. It lives in an Apache-2.0 repository, and you can read the same file for free — home-mixer/filters/brazil_2026_election_filter.rs. The email buys convenience here, not access.

The numeric ids in the file are obfuscated — the repository says so itself. The handles are not.

3 more accounts are named with no country attached
ThunderServiceImplthunder/thunder_service.rs:30
3
accounts written into the source, by id and by handle
unless you follow
their posts, reposts, quotes and thread ancestors are removed from For You — unless the viewer already follows the account
no country test
no country, market or locale condition appears in the filter or where it is registered

No country, market or locale condition appears in the filter file or around the line that registers it. That is a statement about the published code — which pipeline serves which market may be decided in a layer X does not publish.

All 3 accounts, in source order

  • @grok
  • @gork
  • @products

The numeric ids in the file are obfuscated — the repository says so itself. The handles are not.

This list is reproduced from a public Apache-2.0 repository, which states the handles are included for transparency. We report what the code does. We do not endorse, verify or judge the reports that placed any account here.

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.