Back to Blog
x-algorithmtwitter-growthsocial-media-strategycontent-strategyx-marketing

Inside X's Open-Sourced Algorithm: What Actually Ranks in 2026

M
Mel Owen
14 min read

Correction, August 15, 2026: This post originally said an author reply was worth roughly 150 times a like, a direct reply roughly 27x, and a negative signal roughly 200 likes. Those figures were 2023-era ratios that had been circulating for years and got repeated here as if they described the ranking code X actually open-sourced in 2026. They don't. Worse, that whole "worth N likes" framing turns out to be a documented misreading of how these weights work at all, X's own source code has a comment that says so directly. We've rewritten this post against the real constants in home-mixer/params/param.rs at github.com/xai-org/x-algorithm, and we've dropped the exchange-rate framing entirely rather than just plugging in new numbers. The central argument still holds: replies and quotes genuinely outrank likes, and negative signals genuinely cost far more than positive ones. What's gone is any claim that you can convert one into a count of the other. For the fuller writeup, including what X did not open-source and the exact wording of the code comment on this, see X Open-Sourced Its Algorithm: The Real Numbers.

X open-sourced its ranking code in January 2026, and the file that sets the actual scoring constants, home-mixer/params/param.rs, is short enough to read in five minutes. It weights a reply at 5.0 and a like at 0.5. It weights a report at -234.0. Those aren't small gaps, and the ordering they encode is the same one most accounts have backwards: a like is the cheapest, least-weighted signal in the whole system, and a report is the single most expensive thing that can happen to a post. If you've been optimizing for the wrong signal for years, you're not alone, you just haven't seen the weights until now.

This isn't a leak or a scraped screenshot. X put the ranking code out in the open, and creators and researchers have spent months picking through it, sometimes getting it wrong in the process, including in an earlier version of this post. The picture that emerges is less mysterious than the old "the algorithm hates me" theories, and more mechanical: a handful of signals dominate, one category of signal is punished heavily, and the file itself is careful to warn readers away from the exact kind of oversimplified math that's easy to reach for when you're staring at a list of numbers.

What the weights actually are, and what they aren't

Before the hierarchy, one piece of context that changes how you should read every number below. These constants aren't a menu where a reply "costs" or "earns" a fixed number of likes. Per the file's own comments, each weight multiplies a predicted probability that a given viewer takes that action on a given post, not a raw count of how many times it happened. The scoring formula sums weight × predicted_probability across all the possible actions for each candidate post. A comment sitting directly above the constants in param.rs calls out this exact misreading by name: it says treating the ratios as "count equivalences," and specifically the claim that "one report cancels 468 likes," is incorrect, because the weights apply to predicted probabilities rather than raw counts. It also notes that the baseline probability of a report is over 1,000x lower than the baseline probability of a like, which is part of why the report weight has to be so large just to register in the score at all.

So everything below is a real, current weight from a real file, and the ordering is meaningful. What you shouldn't do, and what the earlier version of this post did, is convert those weights into a "worth N likes" or "cancels N likes" statement. That's a category error the source code itself flags.

The signal hierarchy nobody built their strategy around

Likes are the easiest thing to give a post and, per the published weights, the lightest signal in the whole system. What actually carries more weight is anything that shows real intent: a reply, a quote, sharing the link directly with someone. The file doesn't give an author's own reply to a comment a separate, larger weight than any other reply, it's one ReplyWeight constant either way, but that one constant still sits well above a like or a repost.

Here's the hierarchy, straight from home-mixer/params/param.rs, as of August 15, 2026:

| Signal | Weight in param.rs | What it tells the algorithm | |---|---|---| | Share via copy link | 20.0 | Someone valued this enough to hand it to a specific person | | Reply | 5.0 | Real conversation, not a glance, whether it's a reply to your post or your own reply in the thread | | Quote | 5.0 | Enough reaction to add commentary and re-broadcast it | | Retweet | 1.0 | Passive amplification, low effort | | Like (favorite) | 0.5 | Lowest-effort acknowledgment |

X can change any of these numbers in a future commit. This table reflects the file as of August 15, 2026, so check the source if you're reading this later. And as covered above, these are coefficients in a probability-weighted formula, not an exchange rate, so read the table as "share, reply, and quote outrank retweets, which outrank likes," not as "a reply is worth ten likes."

A few signals people commonly cite in this conversation, profile clicks, extended dwell time, and bookmarks, either aren't weighted the way you'd expect or don't appear here at all. ProfileClickWeight is currently set to 0.0 in the file, meaning a profile click currently carries no ranking weight. There's no bookmark weight anywhere in param.rs. Continuous dwell time and not being dwelled on do have constants (0.004 and -0.02), but they're not directly comparable to the event weights above, so the honest takeaway there is the sign, not a number: being read helps, being scrolled past hurts.

That's still a genuinely different game than the one most accounts are playing. If your content is optimized to be liked, it's optimized for the lightest signal in the system. Content built to earn a reply, and then get a reply back from you, is optimized for a signal the file weights well above a like.

The signal that costs the most: report

The flip side is where it gets brutal, and the numbers are steeper than the earlier version of this post claimed. Here's the negative side of home-mixer/params/param.rs:

| Signal | Weight in param.rs | |---|---| | Not interested | -43.2 | | Block author | -31.2 | | Mute author | -58.8 | | Report | -234.0 |

Notice a mute is weighted worse than a block. And a report's weight, at -234.0, is by a wide margin the single largest number in the file, positive or negative.

That's exactly the number the source code's own comment uses as its example of a misreading, so it's worth repeating in full here rather than paraphrasing it away: "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." The model isn't tallying up real likes and real reports on a single post and netting them against each other. It's weighting the predicted probability of each action for each viewer, and reports are rare enough that the weight has to be large just to move the score at all. The comment also points out that recommendations are personalized, so a wave of bad-faith reports mostly affects what gets recommended to people similar to the reporters, not the post's ranking for everyone.

What that leaves standing, and it's still a real finding, is the shape: negative-action weights are far larger in magnitude than positive-action weights, and report is the outlier even among those. That's a good reason to avoid giving anyone cause to actively reject your content. It's not a good reason to calculate exactly how many likes you'd need to "offset" a report, because the file tells you directly that math doesn't represent how the score works.

This changes how you should think about reach. It's not just "get more positive engagement," it's "avoid giving anyone a reason to actively reject this." A post that's mildly annoying to a broad audience, even if a smaller group loves it, can get buried by its own negative signal before the algorithm ever finds the people who'd enjoy it. Precision targeting your hook and your framing to the audience who actually wants this content matters more than casting the widest possible net.

Tone, sentiment, and what we couldn't verify

An earlier version of this post claimed there's a dedicated "sentiment layer" in the released code that scores the emotional tone of a post directly, suppressing combative or outrage-driven content even when raw engagement looks strong. We went looking for that constant in the public repo, across home-mixer, the safety and abuse-detection directories, and the docs, and could not find a documented sentiment- or tone-scoring model to point to. That doesn't prove one doesn't exist somewhere in X's non-public model training, only that the open-sourced code doesn't show it, so we're not going to state it as fact here anymore.

What is documented, and produces a similar practical effect without needing a separate tone model to explain it: the negative-action weights above already make it expensive for a post to provoke someone into reporting, blocking, or muting the account. Content that's designed to pick a fight is more likely to trigger exactly those reactions, and those reactions are weighted heavily in the file whether or not the ranker is also independently reading tone. Calm, verifiable, receipts-over-rhetoric posting is still the safer bet, we just can't cite a specific sentiment constant as the reason anymore.

See how TimeToPost can help you implement these strategies.

The first hour: good practice, not a documented constant

An earlier version of this post also claimed the released weights treat engagement in the first 30 to 60 minutes after posting as a large multiplier on everything that follows. We looked for a velocity, early-engagement-window, or time-decay constant in home-mixer/params/param.rs and the rest of the repo and did not find one. There are half-life constants elsewhere in the codebase, but they govern a 100-day decay window for a completely different system (long-term interest graphs), not a post's first hour. So we can't point to a released constant that supports the "first 30 to 60 minutes" claim, and we're removing it as a stated fact.

The general advice underneath it is still reasonable as an operating heuristic, not because the code proves it, but because a real-time ranking system that's already scoring replies and quotes far above likes rewards a post that's actively generating those signals, and a post nobody is around to reply to generates fewer of them. Treat what follows as practical advice, not something pulled from the weights:

  1. Post when your audience is online, not when it's convenient for you. A 9am post to a mostly-US audience posted at midnight your time still needs to land at their 9am.
  2. Stay near the post for the first hour. Replies and quotes are weighted well above likes in the published constants, and you can't get replies to a post nobody sees or interacts with.
  3. Reply to every early comment, especially the first few. It's a heavily weighted signal, and it also seeds the conversation that pulls in more replies.
  4. Don't dump five posts in that window competing with yourself. One post getting genuine replies beats three posts splitting a thin trickle of attention three ways.
  5. Check back at hour two and three, not just hour one. Sustained engagement is a reasonable proxy for a healthy post even without a documented velocity bonus behind it.

If you haven't nailed down when your specific audience is active in the first place, the best time to post in 2026 breaks down how to find that window instead of guessing at it. None of this requires new content, it requires being present for content you already made. If you're scheduling posts to hit that window automatically but stepping away right after, you're capturing part of the opportunity and leaving the reply signal on the table.

What this actually changes about how you should post

Put the pieces together and the strategy shift is fairly clean, even without any of the exchange-rate math the earlier version of this post leaned on. Stop writing for likes and start writing for replies: ask a real question, take a position someone will want to respond to, leave room in the post for someone to add something. Then actually reply back, because that's the signal the file weights well above a like. Avoid content that's engineered to provoke anger rather than genuine reaction, since the negative-action weights make that expensive regardless of whether a separate tone model is reading it too. And show up for your own post instead of disappearing right after you queue it, since you can't earn a reply-weighted signal from a conversation you're not part of.

If you're tracking your own numbers to see which of your posts are actually working, dwell time and reply rate are worth watching more closely than likes or follower counts, and the analytics most people ignore that actually predict growth walks through which numbers to watch instead of vanity metrics.

Ship the queue, keep the reply window

The algorithm didn't get harder to please, it got more honest, in the literal sense that you can now read the weights yourself, about what it was always going to reward: real conversation over passive scrolling, and showing up instead of posting and disappearing. TimeToPost handles the part that's pure logistics, queuing posts for the windows when your audience is actually online on X today, with Instagram, TikTok, Threads, and Facebook publishing coming soon, so the only thing left for you to do is the one thing the published weights actually reward: showing up and replying.

If you're running this through an AI agent or an automation stack, TimeToPost's API and MCP server let a coding agent schedule the post for the right window directly, so the timing half of this is handled without you opening a dashboard.

Ready to stop guessing and start posting for the signals that actually count? Sign up for TimeToPost and get your queue hitting the windows that matter.

FAQ

What does the X algorithm reward most in 2026?

Per the constants in home-mixer/params/param.rs, the heaviest positive-signal weights are Share via copy link (20.0), then Reply and Quote (5.0 each), well above Retweet (1.0) and Like (0.5). These are coefficients in a probability-weighted scoring formula, not a literal "worth N likes" exchange rate, X's own source comments warn against reading them that way, but the ordering is clear: shares, replies, and quotes outrank retweets and likes by a wide margin.

Do likes even matter anymore on X?

They still count, but they're weighted at 0.5, the lightest positive signal in the published constants. A post earning genuine replies (weighted 5.0) or quotes (5.0) is being scored on a heavier signal than one that only racks up likes.

How much does a mute or block actually hurt my reach?

The published weights are steep: Not interested is -43.2, Block author is -31.2, Mute author is -58.8, and Report is -234.0, all measured against a like's 0.5. Notably, a mute carries a larger negative weight than a block. The file's own comments explicitly warn against converting these into a "this many likes cancelled" figure, since they're coefficients on predicted action probabilities rather than raw counts, but the magnitude gap between negative and positive weights is real, and report stands out even among the negative signals.

Does posting angry or controversial content still get more reach on X?

We could not find a documented sentiment- or tone-scoring constant in the public repo confirming a dedicated mechanism for this. What is documented is that negative-action weights (not interested, block, mute, report) are weighted far more heavily than positive ones, so content that provokes those specific reactions is expensive by design, independent of whether a separate tone model is also involved.

Why does the first hour after posting matter so much?

We could not verify a specific "first 30 to 60 minutes" multiplier in the open-sourced ranking code, and we've removed that claim from this post. Being present to reply early is still reasonable practice, since replies and quotes are weighted well above likes in the published constants, but we can't point to a released velocity constant the way we can for the engagement weights above.

Related posts

Put these strategies into action

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