Back to Blog
x-twitteralgorithmrankingvisibilityopen source

X Open-Sourced Its Algorithm: The Real Weights, and Why They Aren't a Likes Exchange Rate

M
Mel Owen
11 min read

Correction, August 15, 2026: An earlier version of this post converted the weights below into a likes exchange rate, stating things like "a reply is worth 10 likes" and "a report cancels 468 likes." That framing is wrong, and X's own source code says so directly in a comment sitting right above these constants, which we quote in full further down. The weights are coefficients on model-predicted probabilities, not a conversion rate between real engagements. We've rewritten this post to state the real numbers without that framing, and to explain what the weights actually measure instead. We're leaving this note up rather than quietly fixing it, because the corrected version is more useful once you understand what mistake it's correcting.

On January 19, 2026, X published a rewritten version of its ranking algorithm at github.com/xai-org/x-algorithm, Apache-2.0 licensed. Two days ago, on August 13, the repo got a 10 to 15x expansion. It now sits at over 30,000 stars, and for the first time in years the scoring constants that decide what your posts are worth are sitting in a public file anyone can read.

Alongside the code, X shipped something quieter and arguably more useful: a pilot feature called Under the Hood that lets qualifying accounts download a JSON file showing the visibility labels X actually applied to their account over the past month.

This guide covers four things: what the published weights actually are, why the ratio math that circulated after the release is wrong, how to get and read your Under the Hood file, and where the honest limits of both sit. Everything below was verified against the repo on August 15, 2026. These values can change any time X pushes a commit, so treat the file paths as the source of truth, not this post.

The real weights, from the real file

The engagement scoring constants live in home-mixer/params/param.rs. Here they are, exactly as published:

| Signal | Weight | |---|---| | Favorite (like) | 0.5 | | Retweet | 1.0 | | Reply | 5.0 | | Quote | 5.0 | | Share via copy link | 20.0 | | Not interested | -43.2 | | Block author | -31.2 | | Mute author | -58.8 | | Report | -234.0 | | Continuous dwell time | 0.004 | | Not dwelled | -0.02 |

A note on other numbers you may have seen. Earlier writeups, including our own from July, worked from reported ratios circulating at the time, such as an author reply being worth around 150 likes. Those figures don't match the table above, which is why we corrected that post too. But the deeper problem, and the reason this post exists in its current form, isn't just that the old ratios were stale. It's that converting any of these weights into a "worth N likes" statement is the wrong operation entirely, on old numbers or new ones. Keep reading.

What these weights actually multiply

Right above the constants in home-mixer/params/param.rs, X left a comment addressing exactly the mistake that spread after this release, quoted here in full because it's the single most important sentence in the file:

"One common misinterpretation is that you can read these weight ratios as count equivalences, e.g. the incorrect statement that 'one report cancels 468 likes' -- this is incorrect because the weights apply to the predicted probabilities rather than raw counts. And the baseline probability of a Report is more than 1000x lower than a Like, so it's weighted more to allow the prediction to affect the final ranking at all."

Unpack that, because it changes what the table above is actually saying. The ranking system doesn't tally up how many likes and reports a post received and net them against each other. For each candidate post shown to each viewer, it predicts the probability of every action, P(favorite), P(reply), P(report), and so on, then sums weight × predicted_probability across all of them into a single score. The weight is a coefficient inside that formula, not an exchange rate between two real-world events.

That reframes the negative numbers in a way that's more interesting than the exchange-rate version was. A report's weight isn't -234.0 because a report is "468 times worse" than a like in some emotional or business sense. It's that large specifically because reports are rare: the comment states a report's baseline probability is over 1,000x lower than a like's. A tiny probability multiplied by a small weight would barely move the score at all, so the weight has to be large just to let a rare-but-important prediction register. Big negative coefficient means rare and consequential, not "worth hundreds of your positive engagement." The comment adds a second, practical point: because scoring is personalized per viewer, a wave of bad-faith reports from coordinated accounts mainly affects what gets recommended to people who resemble those accounts, not the post's ranking for everyone.

None of that erases the real signal here. Negative-action weights are dramatically larger in magnitude than positive-action ones, and report is the largest of all. That asymmetry is genuine and worth planning around. What isn't real is a specific count of likes that offsets it, in either direction.

The two dwell constants (0.004 for continuous dwell time, -0.02 for not dwelling) come without documented units next to them either, so the same caution applies: read the sign, not a computed ratio. Being scrolled past hurts you, being read helps you, and the penalty for a skip is fixed while the reward for reading scales with attention.

Reach beyond your followers is discounted

Two more constants from the same parameter set:

  • Out-of-Network Weight Factor: 0.75
  • Topic Out-of-Network Weight Factor: 0.5

When X considers showing your post to someone who does not follow you, the post's score is multiplied down: to 75 percent generally, and to 50 percent when the match is topic-based. Out-of-network distribution has a higher bar by design. If your strategy depends on reaching strangers, your content is competing at a built-in discount, which is another way of saying the engagement quality signals above matter even more.

X also scores you, not just your posts

The repo includes an account-level credibility score in user-cred-v2/UserCredV2.scala:

rawScore = 165.2 + 7.07 * ln(mass)

clamped to a 0 to 100 range. The mass input is internal to X and not derivable from anything you can download, so no outside tool can compute your score. What the file proves is simply that a per-account credibility number exists and feeds ranking. Worth knowing; not worth obsessing over, since you cannot observe it.

What was NOT published: the model

This part matters more than most coverage admitted. The release contains the ranking logic and the constants, but no trained model weights. The README in the phoenix directory says it plainly: "there is no checkpoint or corpus bundle to fetch."

The practical consequence: nobody outside X can run X's production ranking. Any tool, thread, or consultant claiming to compute "your real algorithm score" is bluffing. What can honestly be done is checking behavior and data against the published logic and constants, which is exactly what this post is doing, and exactly where the claim has to stop.

See how TimeToPost can help you implement these strategies.

Under the Hood: X's own answer to the shadowban question

For years the only "shadowban checkers" available worked by probing X's search results from the outside and guessing. Under the Hood replaces guessing with a primary source: a downloadable JSON file listing the visibility labels X applied to your account over the past month.

Eligibility, as announced for the pilot phase:

  • 10 or more posts per month
  • account at least one year old
  • inclusion in the pilot rollout

If you qualify, the download option appears in your account settings. The rollout is gradual, so absence of the option means the pilot has not reached you yet, nothing more.

How to read the file once you have it:

  1. The labels are X's own statement. Every entry is X telling you a specific visibility label was applied, with timing. This is categorically better evidence than anything a third-party probe can produce.
  2. Applied does not mean explained. The file shows which labels were applied. It does not say why, and, as TechCrunch noted when the feature shipped, it does not explicitly confirm or deny whether you were shadowbanned. A label list is a fact; "shadowbanned: yes/no" is an interpretation the file refuses to make, and you should distrust anyone who makes it for you.
  3. Absence of labels is genuinely good news, with a scope limit: it covers the past month and the labels this export includes, not the entire history of your account.

What your regular data archive can and cannot do

The standard X data archive (Settings, then download an archive of your data) is available to everyone, and it is worth knowing its exact limits, because they surprise people:

  • It contains no visibility or filtering data at all. Nothing about labels, nothing about restrictions.
  • It contains no impression or view counts, and no reply counts on your posts.
  • Your posts carry favorite and retweet counts as a snapshot at export time, not a history.
  • follower.js and following.js are lists of numeric account IDs, not names.

So the archive can tell you what you posted, when, and how many likes and retweets each post had on export day. Combined with the published weights, that supports an honest audit of your own posting behavior, reply share, link share, cadence, but it doesn't let you compute a live score, because the weights apply to a model's predicted probabilities at ranking time, not to your archived counts. It cannot tell you anything about whether your reach was limited. Any tool that claims to detect visibility problems from an archive alone is claiming something the file does not contain.

One more honest gap: link posts and hashtags. Both are endlessly theorized about, and as of the August 13 expansion I could not find a published penalty constant for either in the repo. That does not prove no penalty exists inside the trained model; it proves the open release does not state one. The difference between those two sentences is the difference between evidence and folklore.

What to actually do with the numbers

The published constants compress into three working rules, none of which require the exchange-rate math this post used to run:

  1. Optimize for replies and shares, not likes. Reply and quote each carry a weight of 5.0 against a like's 0.5, and share via copy link carries 20.0. Content built to be answered or sent to a friend is scored on a heavier signal than content built to be agreed with.
  2. The downside dominates, and it's dominated by rarity, not just severity. Report's -234.0 weight is large because reports are rare and the model needs a big coefficient to let that rare signal matter. In practice that still means content a fraction of readers find baiting, misleading, or spammy is negative-sum, even when the engagement screenshot looks great. Calm posts age better in this scoring than combative ones.
  3. Get read, not scrolled past. The dwell constants reward posts that hold attention. Front-load the substance; the skip penalty is flat and instant.

None of this requires believing X's marketing, or believing anyone's conversion of these weights into a likes count, including our earlier version of this post. It requires reading home-mixer/params/param.rs, which you can do yourself right now.

FAQ

Did X release its actual algorithm?

X released the rewritten ranking logic and scoring constants at github.com/xai-org/x-algorithm under an Apache-2.0 license, and expanded the repo roughly 10 to 15x on August 13, 2026. It did not release the trained model weights, so the code shows how scoring works but cannot be run as X runs it.

What is the most valuable engagement on X?

Per the published constants in home-mixer/params/param.rs, share via copied link carries the highest positive weight at 20.0. Reply and quote are each weighted 5.0, retweet is 1.0, and favorite (like) is 0.5. These are coefficients in a probability-weighted scoring formula, not a likes exchange rate, but the ordering holds: shares, replies, and quotes outrank retweets and likes.

Is it true that one report cancels out hundreds of likes?

No, and this is a documented misreading, X's own source code comment in home-mixer/params/param.rs calls it out directly. The report weight (-234.0) is large because reports are rare, its baseline probability is over 1,000x lower than a like's, so a large coefficient is needed just to let that rare prediction affect ranking at all. The weights multiply predicted probabilities per viewer, not raw counts on a single post, so there's no valid count of likes that "cancels" a report. What is true, and doesn't require the exchange-rate math, is that negative-action weights are far larger in magnitude than positive ones, and report is the largest.

How do I get my Under the Hood file?

Under the Hood is in a pilot phase. Accounts that post 10 or more times per month and are at least a year old are eligible as the rollout reaches them, and the download appears in account settings as a JSON file covering the past month of applied visibility labels.

Can any tool tell me definitively if I am shadowbanned?

No. The Under the Hood export shows which visibility labels X applied, and it does not explicitly confirm or deny shadowbanning. The standard data archive contains no visibility data at all. A tool can show you X's own labels and explain the published ranking constants; a yes or no shadowban verdict goes beyond what any available data supports.

Related posts

Put these strategies into action

TimeToPost helps you schedule content, track performance, and grow your audience, all in one place.