Back to blog

X's Algorithm Open in 2026: Copying a Link Is Worth 40 Likes

Hello HaWkers, the xai-org/x-algorithm repository on GitHub has a configuration file called params.rs, inside the vm-ranker folder, that became a hot topic this week. It contains, in plain text, the weights X uses to decide what shows up in the "For You" feed. And the numbers are very different from what most people imagine: copying a post's link weighs 20.0, a reply weighs 5.0 and a like weighs only 0.5. Visiting the author's profile weighs exactly 0.0.

Do the math: copying the link is worth 40 likes. And a report weighs -234.0, the equivalent of wiping out 468 likes at once.

If you post on X, whether to promote a project, look for a job or just talk about tech, the question is straightforward: are you optimizing for the metric the algorithm actually values? In this article I will show what the code says, how the final score is calculated, what these weights do not mean (there is a lot of misreading going around) and how to simulate the score in JavaScript to understand the effect of each signal.

What X Opened, and When

This is not the first time the network has opened its recommendation code. On March 31, 2023, still as Twitter, the company published the twitter/the-algorithm repository. Back then, the ranking model README had a famous weights table: reply at 13.5, like at 0.5 and report at -369.0.

The current version is a different project, with a different architecture. According to the history of the xai-org/x-algorithm repository:

  • January 20, 2026: first release, with the code for Home Mixer, Thunder and Phoenix, under the Apache 2.0 license.
  • May 15, 2026: second batch, with the inference pipeline and a reduced version of the Phoenix model.
  • August 13, 2026: the big update, which brought the scoring weights, the visibility filters and Phoenix's trainable code.
  • October 2026: the README logs tweaks such as improved prediction of time spent reading (October 8) and retrieval trained on posts people read all the way through (October 13).

One important point: the trained weights of the production model were not published. What is open is the code, the configuration and a demo model. So you can understand the logic, but you cannot run X's feed on your machine.

How a Post's Final Score Is Calculated

The most misunderstood part of this whole story is right here. The repository README describes the formula like this:

Final Score = Σ (weight_i × P(action_i))

The Phoenix model, a Grok-based ranking transformer, takes your history and a candidate post and predicts the probability that you will take each action: like, reply, share, report and so on. The weights multiply those probabilities, not the raw count of likes the post already has.

That changes everything. The 20.0 weight for "copy link" does not mean every copied link on your post is worth 20 points forever. It means that when the model thinks it is likely that that person will copy the link of that post, the post climbs high in their queue.

The repository itself warns against the naive reading: it is not correct to see that a report weighs hundreds of times more than a like and conclude that one report cancels hundreds of likes. The probability of someone reporting an ordinary post is tiny, so the negative term is usually small in the sum.

The Full Table of Positive Weights

These are the values from the vm-ranker/params.rs file, in the version that circulated this week:

Action Parameter Weight
Share by copying the link ShareViaCopyLinkWeight 20.0
Reply ReplyWeight 5.0
Share via DM ShareViaDmWeight 5.0
Quote QuoteWeight 5.0
Follow the author FollowAuthorWeight 4.0
Share (generic) ShareWeight 2.0
Repost RetweetWeight 1.0
Like FavoriteWeight 0.5
Time reading after click ContClickDwellTimeWeight 0.4
Click the post ClickWeight 0.3
Open external link OpenLinkWeight 0.2
Open video VideoOpenWeight 0.07
Expand photo PhotoExpandWeight 0.05
Click the profile ProfileClickWeight 0.0

Three takeaways jump out:

  1. Sharing off-platform is king. Copying the link is the strongest signal of all. It makes sense from a product standpoint: whoever copies a link is taking the post to WhatsApp, to Slack, to a group chat. It is the strongest proof that the content has value outside the bubble.
  2. Conversation is worth more than applause. Replies, quotes and DMs weigh 10 times more than a like.
  3. Reposts are worth little. At 1.0, a repost sits well below a reply. The algorithm prefers the post that sparks conversation over the post that is merely replicated.

The Negative Signals

On the other side of the scale, the file has the weights that sink a post:

Action Parameter Weight
Report ReportWeight -234.0
Mute the author MuteAuthorWeight -58.8
"Not interested" NotInterestedWeight -47.52
Block the author BlockAuthorWeight -31.2
Scroll past without reading NotDwelledWeight -0.02

Notice that muting weighs almost twice as much as blocking. One possible reading: someone who mutes keeps following but clearly says "I don't want to see this", while a block is often about the person, not the content. The code has no comments explaining the choice, so treat this as a hypothesis.

Compared with the 2023 table, reports became less punitive (from -369.0 to -234.0) and replies lost strength (from 13.5 to 5.0). The big winner of the change is link sharing, which did not even stand out in the old version.

Simulating the Score in JavaScript

To feel the effect of the weights, nothing beats code. The example below uses the real values from params.rs and made-up probabilities for two hypothetical posts. The probabilities are illustrative: on X, Phoenix is what calculates them.

// Weights copied from vm-ranker/params.rs (xai-org/x-algorithm)
const PESOS = {
  favorite: 0.5,
  reply: 5.0,
  retweet: 1.0,
  quote: 5.0,
  shareViaDm: 5.0,
  shareViaCopyLink: 20.0,
  followAuthor: 4.0,
  click: 0.3,
  profileClick: 0.0,
  notInterested: -47.52,
  muteAuthor: -58.8,
  blockAuthor: -31.2,
  report: -234.0,
};

// Score = sum of weight × predicted probability of each action
function calcularNota(probabilidades) {
  return Object.entries(probabilidades).reduce((soma, [acao, p]) => {
    const peso = PESOS[acao] ?? 0;
    return soma + peso * p;
  }, 0);
}

// "Hot take" post: lots of predicted likes, but it annoys people
const postPolemico = {
  favorite: 0.12,
  reply: 0.03,
  retweet: 0.02,
  notInterested: 0.01,
  muteAuthor: 0.004,
  report: 0.001,
};

// Useful post: few likes, but people save it and send the link
const postUtil = {
  favorite: 0.04,
  reply: 0.01,
  shareViaCopyLink: 0.015,
  followAuthor: 0.005,
};

console.log('Polêmico:', calcularNota(postPolemico).toFixed(4));
console.log('Útil:', calcularNota(postUtil).toFixed(4));

Running it in Node.js, the hot take post lands around -0.71 and the useful one at 0.39. The first has three times more predicted likes and still loses, because a 1% chance of "not interested" already costs almost 0.48 points, the chance of muting takes away another 0.24 and the small chance of a report takes another 0.23. The second wins because a 1.5% chance of someone copying the link adds 0.3 on its own.

Author Diversity and the Out-of-Network Factor

The raw score is not the end of the story. After Phoenix, Home Mixer applies adjustments that also show up in params.rs:

  • AuthorDiversityDecay = 0.5 and AuthorDiversityFloor = 0.25: each subsequent post from the same author in the same batch is multiplied by a decaying factor, with a floor. Posting in bursts does not multiply your reach.
  • OonWeightFactor = 0.75: posts from accounts the person does not follow ("out of network") have their score multiplied by 0.75. There is also TopicOonWeightFactor = 0.5 for topics.
  • DppEnabled = true with DppTheta = 0.65: vm-ranker reorders the feed with a determinantal point process over the post embeddings. In plain English: it trades a bit of score for less repetition between neighboring posts.

You can model the author decay like this:

const DECAIMENTO = 0.5; // AuthorDiversityDecay
const PISO = 0.25; // AuthorDiversityFloor
const FATOR_FORA_DA_REDE = 0.75; // OonWeightFactor

// Applies the multipliers in the order the posts appear
function ajustarFeed(candidatos, segue) {
  const vistosPorAutor = new Map();

  return candidatos
    .sort((a, b) => b.nota - a.nota)
    .map(post => {
      const ocorrencias = vistosPorAutor.get(post.autor) ?? 0;
      vistosPorAutor.set(post.autor, ocorrencias + 1);

      // Author's first post: factor 1. Then: 0.5, 0.25, 0.25...
      const diversidade = Math.max(DECAIMENTO ** ocorrencias, PISO);
      const rede = segue.has(post.autor) ? 1 : FATOR_FORA_DA_REDE;

      return { ...post, notaAjustada: post.nota * diversidade * rede };
    })
    .sort((a, b) => b.notaAjustada - a.notaAjustada);
}

const feed = ajustarFeed(
  [
    { id: 1, autor: 'ana', nota: 0.9 },
    { id: 2, autor: 'ana', nota: 0.85 },
    { id: 3, autor: 'bruno', nota: 0.7 },
    { id: 4, autor: 'ana', nota: 0.8 },
  ],
  new Set(['ana']) // the person only follows Ana
);

console.table(feed);

The result shows Bruno's post, which had the third highest raw score, overtaking Ana's second and third posts. Even with the out-of-network discount (0.7 × 0.75 = 0.525), it beats 0.85 × 0.5 = 0.425 and 0.8 × 0.25 = 0.2. That is the mechanism that keeps a single account from dominating your feed.

The real implementation is subtler (the exact point where the decay is applied depends on the pipeline), but that is the intuition.

What This Means for People Who Post

Now the practical part. If you use X to share technical work, the weights suggest a few habit changes:

Write to Be Saved and Passed Along

A thread with a step-by-step guide, a code snippet that solves an annoying problem, a comparison table: this is the kind of content people copy the link of and send to their team. That is exactly the strongest signal in the table.

Spark Conversation, Not Fights

A reply is worth 5.0, but "not interested" costs -47.52 and muting costs -58.8. An honest question at the end of a post generates replies; a gratuitous provocation generates replies and mutes. The math goes negative fast, as the simulation showed.

Don't Count on Profile Visits

ProfileClickWeight is set to 0.0. The "mysterious post so people click your profile" strategy gains nothing in ranking. Following the author, on the other hand, weighs 4.0, so what counts is content that convinces the person to hit the button.

Spread Out Your Posts

With a 0.5 decay per post from the same author, five posts in a row compete against each other. One strong post beats five average ones in sequence.

This topic connects with a change that already showed up here on the blog, when X started using AI to organize the feed. If you want the context, it is worth reading how Grok started organizing posts on X.

An Exercise for Devs: Weighted Ranking in Your Product

The "weighted sum of probabilities" logic is not exclusive to social networks. Any product with a feed, search or recommendation list can use the same structure. The snippet below shows a generic ranker, with configurable weights and a diversity penalty, that you can adapt for a marketplace or a blog:

// Configuration separated from the code, like X's params.rs
const config = {
  pesos: { clique: 0.3, salvar: 4.0, compartilhar: 10.0, ocultar: -30.0 },
  decaimentoPorCategoria: 0.6,
  pisoDiversidade: 0.3,
};

function ranquear(itens, preverProbabilidades, cfg = config) {
  const pontuados = itens.map(item => {
    const probs = preverProbabilidades(item);
    // Weighted sum: the same principle as X's formula
    const nota = Object.entries(cfg.pesos).reduce(
      (acc, [acao, peso]) => acc + peso * (probs[acao] ?? 0),
      0
    );
    return { ...item, nota };
  });

  // Penalizes repeated categories so the feed doesn't become one-note
  const vistos = new Map();
  return pontuados
    .sort((a, b) => b.nota - a.nota)
    .map(item => {
      const n = vistos.get(item.categoria) ?? 0;
      vistos.set(item.categoria, n + 1);
      const fator = Math.max(cfg.decaimentoPorCategoria ** n, cfg.pisoDiversidade);
      return { ...item, nota: item.nota * fator };
    })
    .sort((a, b) => b.nota - a.nota);
}

The most valuable engineering lesson from X's repository may be this one: weights in a configuration file, separate from the model. That lets you tune product behavior (give more value to sharing, punish "hide" harder) without retraining anything, and it lets you test variations through A/B tests. params.rs even has a WeightPerturbationSigma parameter, currently at 0.0, which hints at the possibility of perturbing weights for experiments.

The Limits of What Was Opened

Before turning the table into dogma, it is worth remembering what is not in the repository:

  • Phoenix's trained weights. The probabilities that go into the formula come from a model that remains closed. Knowing that copying a link weighs 20.0 does not tell you when the model will predict that someone copies the link.
  • Active experiments. The code shows the default configuration, but the repository itself records experiment override maps. Two people may be under different weights on the same day.
  • The visibility layer. Brand safety, spam and moderation filters run before and after ranking. A post can have a great score and never reach the feed.

Even so, few large platforms leave this level of detail in plain sight. For anyone studying recommendation systems, the repository is rare study material, with Rust code from a system running at real scale.

Outlook: Transparency or Instruction Manual?

Opening the weights has two effects that pull in opposite directions. On one hand, researchers and users can audit what the platform rewards, something transparency advocates have been asking for for years. On the other, every content creator now has an optimization manual, and the trend is to see a flood of posts asking you to "copy the link and send it to a friend".

If that happens at scale, X will probably adjust the weights again, as it already did between 2023 and 2026. The numbers in the table are a snapshot, not a law. What should hold is the principle: content that people take off the platform and that sparks conversation without irritation tends to win. And that, interestingly, is a good rule for writing about tech anywhere.

Let's go! 🦅

📚 Want to Keep Up With What Is Coming?

This article covered the weights of X's algorithm and how a post's score is calculated, but the ecosystem changes every week and not everything becomes an article here.

On X I share what I am testing, the behind-the-scenes of my projects and the news that shows up before it becomes a post.

Follow Me There

👉 Follow @jeffbruchado on X

💡 Daily content about development, career and the tools I actually use

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments