What the X algorithm actually rewards
X publishes the code that decides your feedAlmost nobody has read it. It is one file, and it is shorter than this article.
Almost everything you have read about the X algorithm is from 2023.
That was the first time X open-sourced it. Scala, hundreds of hand-tuned signals, a reputation score called TweepCred. Post at 9am. Never put a link in a post. Threads beat single posts. Every tip still circulating traces back to that release, and that release has since been thrown away and rewritten.
X has since published the code that actually runs. Not a description of it, not a blog post about it: the ranking itself, weights and all, in a public repository. The surprise is not how complicated it is. It is how little there is to it. You can hold the whole thing in your head at once.
All of it:
- X guesses what you will doFor every post it might show you, it predicts how likely you are to do each of about two dozen things. Reply. Like. Copy the link. Mute the author.
- Each guess gets a priceEvery prediction is multiplied by a number saying what that action is worth. The numbers are in one file, and you can read them in a minute.
- The prices are added upThat total is the post's score.
- Two discounts land on the totalOne for posting repeatedly. One for being a stranger to the reader.
- Everything is sorted by scoreThe top of the list is your feed.
That is it. No reputation score, no time-of-day rule, no penalty for links. Five steps and a list of prices.
The prices are where it gets interesting, because they are not what people assume. A reply is worth ten likes. Someone copying your link is worth forty. A report costs you 468.
Every number below is read off xai-org/x-algorithm on 12 September 2026. I
have marked the places where the repository and the popular summaries of it
disagree, because they disagree more than you would expect.
What happens when you open the app
Eight stages, in order, every time the feed loads. Figure A is the whole of it.
Three thousand posts are consideredAlmost none of them reach you. Run the cursor across them.
3000candidates, every time you open itEvery strand is a post that could have been shown to you.
Three of the eight are plumbing. Query hydration loads who you are: your follows, your blocks, your mutes, what you have already been shown. Candidate hydration attaches the actual text and media to the posts. Blending is where ads and Who to Follow get interleaved at the end.
The two that decide what you see are sourcing and scoring. Sourcing gathers up to three thousand posts you could be shown. Scoring puts them in an order. Everything people call “the algorithm” is the second one.
Worth noticing how brutal the narrowing is. Three thousand candidates go in. The variety reorder only bothers with the top 150. Whatever your post is competing against, it is competing on one number against a few thousand others, and almost none of them survive.
Where the posts come from
Two pipes feed that funnel. Thunder holds recent posts in memory and returns the ones from accounts you follow. Phoenix and SimClusters go and find posts from accounts you don’t.
A stranger's post starts at three quartersThe same post is worth less depending only on how it reached you
25%off, for being a strangerThe part that surprised me: a post from someone you don’t follow is multiplied by 0.75 before anything about it is scored. If it was reached by topic rather than by similarity, it is multiplied by 0.5. The discount is not earned by the post being worse. It is applied for being out of network, in advance, to all of them.
So reaching strangers is not a fair fight, and it was never meant to be. An out-of-network post has to predict roughly a third more engagement than an in-network one to land in the same position.
The model reads you, not your post
Phoenix embeds you and each candidate post as vectors and predicts how likely you are to do each of about two dozen things: like, reply, quote, share, click, dwell, follow the author, mute them, report them.
Two details matter more than they sound like they do.
The first is that it reads your action history, up to 1,024 positions of it. Not the post’s history. Yours. When people say “the algorithm decided my post was bad”, the model did not evaluate the post in isolation at all. It predicted what one specific viewer tends to do with things like it.
The second is that candidates cannot attend to each other during ranking. Each post is scored against your context alone, never against the other posts in the batch. Your score does not depend on who else posted that minute. There is no queue you are at the back of.
How the score is made
Steps two and three, with real numbers in them. One post, five of its predicted actions, and the arithmetic that turns them into the single number everything is sorted by.
How one post becomes one numberA probability per action, each priced, then marked down twice
Sorted against roughly 2,800 others scored the same way. Nothing in the post itself is read twice. The two multipliers land after the model has already decided what you would enjoy.
There is nothing hidden behind that. The rest of this piece is just the prices, where they came from, and what they mean for what you post.
Twenty-one numbers
This is the file. home-mixer/params/param.rs, the weights that multiply each
predicted action into one score. All twenty-one of them, priced in likes,
because a like is the only unit anyone has an instinct for. The top block is
what X pays you for. The bottom block is what it charges you, on a scale of
its own, because it does not fit on the same one.
Read it as a statement of values, because that is what it is. Somebody sat down and decided what a person doing each of these things is worth to X.
Copying your link to send it somewhere else is the single most valuable thing a reader can do, at forty times a like. Replying, quoting and sending by DM are ten times a like. Following you off the back of a post is eight. A like is 0.5, which puts it near the bottom of everything that counts as engagement at all.
Two actions are predicted and then multiplied by zero. Profile clicks and video quality views are both switched off. The model still works out how likely you are to do them, and the ranking ignores the answer.
Then the negatives, which are on a different scale entirely. Block is −31.2. Not interested is −43.2. Mute is −58.8. Report is −234, which is 468 times a like in the other direction.
One caveat, and most versions of this going around get it wrong. These weights multiply predicted probabilities, not counts. A report weight of −234 does not mean one report cancels 468 likes. It means the model’s belief that you might report a post costs 468 times more per unit of belief than its belief that you might like it. Nobody has to actually report anything. The prediction alone does the damage.
It is a hard sentence to feel, so the arithmetic has handles on it below. Put in the numbers you actually see on a post. Views turn the counts back into rates, and the rate is what gets multiplied.
Score a post yourselfCounts go in. Rates are what get scored.
900 likes on 100k views is a 0.90% like rate, and the rate is what the weight multiplies.
Start with the post as it loads: nine hundred likes, a hundred and sixty replies, thirty people who copied the link. A good week. Now drag reports up.
At nine reports the whole thing goes negative. Nine. Against nine hundred likes, because a report is weighted 468 times what a like is, and four hundred and sixty-eight times a small number is still a much bigger number. You cannot win that back on the likes slider even at its maximum.
Drag bookmarks and watch nothing happen. There is no bookmark weight in the file. There is no weight for views either. Two of the numbers X puts on the front of every post are not in the ranking at all.
If you write for one thing, write for the reply. If you avoid one thing, avoid being the post someone mutes.
The one weight with a reason attached
Most of those weights are simply there, with no explanation attached. One of them has a note in the repository explaining how it got to be what it is, and it is the most human thing in the whole codebase.
A reply from a mutual counts tripleSomeone who follows you back, replying to your original post. Move across the field.
3×what a mutual's reply is worthA reply to an original post from someone you follow who follows you back is weighted 15 instead of 5. Mutual follows, triple weight.
It was A/B tested on 10 July 2026 at five values including zero. Twenty won, and shipped to everyone on the 13th. Eleven days later it was cut to fifteen, because the World Cup was on and, in the repository’s own words, “some people weren’t seeing as much discussion of it as they wanted, given many of the posts were from accounts they didn’t follow.”
They turned the dial up on your friends, discovered it had quietly walled people off from a thing the whole world was talking about, and turned it back down. That is a product decision, made in public, with the reasoning attached. I wish more of the file looked like this.
The practical read is unglamorous. Follow back the people who reply to you. Their replies are worth triple, and yours on their posts are too.
The multiplier nobody mentions
After the weighted sum there are adjustments, and they do more to your reach than any posting tip. The first one is below. Press post again a few times and watch your own circles shrink.
Post again and you compete with yourselfEvery extra post of yours in the same feed is worth less than the one before
100%what post 1 is worthYour first post of the day counts for everything it earned.
Each further post from the same author in one feed load gets multiplied down. The second is 0.63 of the first. The third is 0.44. By the fifth you are at 0.30, and it never falls past a quarter, because there is a floor.
So posting five times in an hour hands your fifth post a seventy percent cut before it competes with anyone. Not a penalty for spamming, and nothing to do with quality. It is a diversity rule protecting the reader from a feed that is all you.
Space your posts out. When you want to say another thing right now, reply to someone instead. Replies are worth ten times a like and they do not compete with your own last post.
That is the only pattern in the code that cares how you schedule. Not the hour, not the day. Just how many of yours arrive together.
Spacing, not timingSpread out, every post is worth full weight. Stacked, the column goes dark.
0%of your week, given awayNothing posted yet.
Both multipliers land after the model has already decided what you would enjoy, which is the part I found hardest to picture. So here are six posts going through it one rule at a time.
The same six posts, ranked three timesThe model picks an order. Then two rules that know nothing about the posts rearrange it.
All six scored on how likely you are to act on them, based on what you have done before. On merit the stranger's teardown is the best post here and your launch thread is second.
Step through it. On predicted engagement the stranger’s thread wins and your three posts hold second, third and fourth. Apply diversity and your own posts fall away from each other. Apply the out-of-network discount and the thread that was winning drops behind a question from a mutual it had comfortably beaten.
Nothing about those posts changed. The model’s opinion of them did not change. Two multipliers rearranged the feed after the fact, and neither of them is something you can write your way out of.
What is not in there
The absence of things is the finding. I went looking for the rules everyone repeats and could not find them.
- Links are penalisedNot in the code
- There is no link rule. Opening a link is a positive action at 0.2. If link posts do worse, it is because the model predicts fewer of the actions X pays for.
- One report cancels 468 likesWrong
- The weights scale predicted probabilities, not counts, which makes this specific sentence wrong.
- TweepCred decides your reachNot in the code
- Not in home-mixer. A
user-cred-v2module exists in the repository, the ranking scorer does not call it, and it has no README. - Post at the right timeNot in the code
- No time-of-day rule anywhere. Local hour is an input the model can learn from, which is not the same as a rule you can beat.
- Hashtags trigger the spam filterCannot be checked
- No hashtag rule in ranking. Spam classification lives in Grox, whose prompts are withheld, so this can be neither confirmed nor denied.
- Video beats textWrong
- Video open is 0.07 and video quality view is 0. A text post that earns replies scores far higher than a video that is merely watched.
- Bookmarks are a strong signalNot in the code
- There is no bookmark weight in the file, and none for views either. Two of the numbers X prints on every post are not in the ranking at all.
- Threads get 40 to 60% more reachCannot be checked
- That number is from analytics vendors, not from this code. Each post in a thread is scored on its own.
Also missing: any production model weights. What is published is the architecture, the trainer and the ranking parameters. The trained model is not in there, so nobody outside X can compute a real score for a real post. Anyone selling you a tool that does is selling you a guess.
What I would actually change
Four things follow from the file, and only three of them are things I had believed.
Write for the reply, not the like. This is the biggest gap between what people optimise for and what the code pays for. Twenty to one.
Write things worth sending to one person. The copy-link share is the highest weight in the file by a factor of four over the next one. A post someone DMs to a co-founder is the best outcome available to you.
Space your posts out and reply in between. The decay curve is real and it is steep, and replies sidestep it entirely.
Stop avoiding links. I had this one wrong for years. There is no link penalty in the ranking code. There is a media-card trade-off in how a link renders, and there is the plain fact that a post sending people away earns fewer of the actions that score. Those are different problems from the one everybody warns you about, and only one of them is yours to fix.
The thing I keep coming back to is that the weights are legible in a way the old advice never was. You do not have to guess what the platform wants. It is twenty-one numbers in a file, and it wants replies and it wants your post sent to someone privately, and it really does not care very much whether anyone liked it.
The game plan
Everything above, turned into what to actually do. Ordered by how much the file says it is worth, not by how often you hear it.
- Write for the reply. A reply is ten likes, a quote is ten, a DM share is ten. This is the biggest gap between what people optimise for and what the ranking pays for. End on something a person can answer. A question they have an opinion about beats a question they have to look something up for.
- Write things worth sending to one person. A copied link is forty likes, four times the next best thing in the file and the highest number there is. The test is whether a reader would paste it into a DM with “this is us”. That is usually a specific number, a named mistake, or a screenshot.
- Follow back everyone who replies to you. A reply between two accounts that follow each other is weighted 15 instead of 5. It costs nothing, it triples every future reply in both directions, and it is the only weight X has explained in writing.
- Leave hours between your own posts. Your second post in the same feed load is worth 63% of your first, the third 44%, and it floors at 25%. Waiting is free. The earlier post loses nothing by it.
- Reply to other people in the gaps. Replies carry the second-highest weight in the file and they do not compete with your own last post the way another post does. This is the one thing that gets better the more you do it.
- Stop avoiding links. There is no link rule in the ranking code. If your link posts underperform it is because they earn fewer replies and shares, not because of a penalty. Fix the post, not the URL.
- Do not chase bookmarks or views. Neither has a weight in the file. They are the two numbers X prints largest on every post and the ranking ignores both.
- Protect the downside first. Nine reports cancel nine hundred likes. Mute is 118 likes and not-interested is 86, both in the wrong direction. The ceiling on a great post is far lower than the floor under a post that annoys people, so the cheapest win available is not writing the second kind.
What none of this can tell you is what to say. The weights price actions, not ideas, and the model predicts from what each reader has done before. Someone who has never replied to anything will not start with your post because you ended on a question.
Every weight and multiplier above is read off 1 the candidate caps come from the same file, the order the multipliers are applied in is in the scorer 2 the July dates and the World Cup rationale are quoted from the change note 3 and the pipeline stages and the sentence about predicted probabilities are from the README 4 Snapshot taken 12 September 2026. If a weight has moved since, the repository is right and I am stale. Corrections welcome.