[

[

x algorithm series

]

]

The May 2026 X algorithm: why voice wins when the ranker becomes a transformer

·

·

13 min read

By Prateek Singh, founder of VoiceMoat

By Prateek Singh, founder of VoiceMoat

Summarize with AIClaudeChatGPTPerplexityShareShare

In May 2026, X.AI quietly pushed three commits to a public repository called xai-org/x-algorithm and walked away. No blog post, no launch thread, no developer call. Just a clean drop: 214 KB of source, a 3 GB Git LFS checkpoint, issues disabled. The repo now has 25,000 stars and almost no one writing about it has read it carefully.

We did. The conclusion that came out of that reading is the one this entire series is built around: X's ranker is no longer a feature engineering problem. It is a sequence model. And every piece of "X algorithm advice" that survives from 2020 to 2023 is now wrong in the same specific way.

What actually changed

The 2023 Twitter release (twitter/the-algorithm, twitter/the-algorithm-ml) described a stack we will recognise from anything labelled "modern" in machine-learning recommender systems through about 2022. There was a Scala home-mixer orchestrating a candidate pipeline. There was a MaskNet heavy-ranker scoring a few thousand candidates against around 6,000 hand engineered features. There were three embedding systems running in parallel: SimClusters for community-level signals, TwHIN for graph-aware representations, RealGraph for follow-affinity scores. There was a light ranker, a heavy ranker, candidate-source-specific rerankers, and a serving layer called Navi. Roughly half the team's effort sat in feature engineering for that pipeline.

That entire stack is gone. The May 2026 repo is a wholesale rewrite, and the README does not soften it: "We have eliminated every single hand engineered feature and most heuristics from the system." In place of the 2023 layer cake, X now runs one Grok-derived transformer named Phoenix (phoenix/recsys_model.py) for ranking and a two tower retrieval model (phoenix/recsys_retrieval_model.py) for out of network candidates. The orchestration around them, the home-mixer pipeline (home-mixer/), is now in Rust.

The 2023 stack and what replaced it in May 2026

Layer

2023 release

May 2026 release

Orchestration

Scala home-mixer

Rust home-mixer with candidate-pipeline traits

Ranker

MaskNet heavy-ranker on ~6,000 hand-engineered features

Phoenix transformer with no hand-engineered features

Light ranker

Separate model

Folded into Phoenix

Community signals

SimClusters embeddings

Removed; learned implicitly

Graph signals

TwHIN embeddings + RealGraph follow-affinity

Removed; one boolean in-network flag plus mutual follow

In-network store

Earlybird search index

Thunder in-memory store

Out-of-network retrieval

Mixed candidate sources, source-specific rerankers

Two-tower retrieval (PhoenixRetrieval) plus MoE and topic variants

Trust and safety

Visibility filtering inside home-mixer

Split: vf_filter post-selection plus Grox content service

Engagement signals

10 weights disclosed in the public code

19 action heads, weights redacted from the params module

Inference serving

Navi

Python pipeline (run_pipeline.py) plus value-model gRPC

Source: xai-org/x-algorithm/README.md + repo inventory

Read that table once more and notice what is conspicuously absent on the right column. No similarity clusters. No graph embeddings. No follow affinity score. No hand engineered features. The transformer is expected to learn all of that implicitly from the user's history sequence. That is the shift this article is about. Everything downstream of it, the 19 action heads, the new retrieval architecture, the negative-signal economy, the diversity reranker, falls out of that one design move.

Phoenix in one picture

The diagram below collapses the May 2026 ranker into a single picture. It omits a great deal, but it preserves the four properties that matter for anyone writing on X.

The Phoenix ranker, end to end. Inputs on top, outputs at the bottom.

Viewer history sequence127 tokens, mini checkpoint(past posts plus the actions the viewer took)Candidate postsup to 64 candidates(from Thunder plus 3 OON sources)Token plus author-hash plus position embeddings1M author vocab, 2 hashes per entity, 128-d in the mini checkpointPhoenix transformer (4 layers, 4 heads)Candidates attend to viewer history. Candidates cannot attend to each other.candidate-isolation attention mask19 action-head outputs per candidateP(favorite), P(reply), P(quote), P(repost), P(dwell), P(VQV), ... 13 moreWeighted scorer: Σ P(action_i) × WEIGHT_i

Four properties to lock in before we go further. First, the viewer's history is a sequence, not a summary. The transformer sees a chronologically ordered tape of what the viewer has seen and how the viewer reacted, and self-attention does the rest. Second, the model does not produce one "engagement score." It produces 19 separate per-candidate probabilities, one per supported action. Third, those 19 probabilities feed a weighted linear combination defined in home-mixer/scorers/weighted_scorer.rs that turns into the final score. Fourth, and most important for everything below, the attention mask isolates candidates from each other. When Phoenix scores your post, it cannot see the other posts in the same scoring batch. The score is a function only of you and the viewer.

The 19 action heads and the new scoring math

The 2023 ranker disclosed ten weight constants in its public code. The 2026 ranker exposes nineteen action heads but redacts every numeric weight (the params module is excluded from the open release). What we have are the head names: FAVORITE_WEIGHT, REPLY_WEIGHT, QUOTE_WEIGHT, QUOTED_CLICK_WEIGHT, RETWEET_WEIGHT, PHOTO_EXPAND_WEIGHT, CLICK_WEIGHT, PROFILE_CLICK_WEIGHT, VQV_WEIGHT (video quality view), SHARE_WEIGHT, SHARE_VIA_DM_WEIGHT, SHARE_VIA_COPY_LINK_WEIGHT, DWELL_WEIGHT, CONT_DWELL_TIME_WEIGHT, FOLLOW_AUTHOR_WEIGHT, NOT_INTERESTED_WEIGHT, BLOCK_AUTHOR_WEIGHT, MUTE_AUTHOR_WEIGHT, REPORT_WEIGHT. Plus an implicit not_dwelled_score referenced in home-mixer/scorers/vm_ranker.rs but not the simpler weighted scorer, which is its own minor mystery.

The scoring formula, reproduced from home-mixer/scorers/weighted_scorer.rs, looks like this:

combined = Σ_i (P(action_i) × WEIGHT_i)
final = offset_score(combined)
combined = Σ_i (P(action_i) × WEIGHT_i)
final = offset_score(combined)
combined = Σ_i (P(action_i) × WEIGHT_i)
final = offset_score(combined)

offset_score is an asymmetric clamp. Net positive scores pass through roughly linearly. Net negative scores, where predicted mutes and not interested overwhelm predicted positives, route to a separate branch that rescales by (combined + NEGATIVE_WEIGHTS_SUM) / WEIGHTS_SUM × NEGATIVE_SCORES_OFFSET. The full negative-signal economy (A5 covers it in detail) is the single biggest scoring change creators should internalize from this rewrite. One predicted mute can sink dozens of predicted likes. Every one of those nineteen heads has its own breakdown in A2 of this series, where we split them into the six verifiable from run_pipeline.py index constants and the thirteen we can only infer from the proto field names.

The implication of nineteen heads, not one, is the next compounding property. A post that fires three of the high-weight heads (reply, profile-click, continuous-dwell) ranks above a post that fires one (favorite) with three times the volume. The graph below sketches that effect schematically. It is not from production telemetry; the numbers are illustrative.

Same number of impressions, very different scoring shape under the two rankers: Likes-heavy post: Heuristic ranker (2023 shape) 70, Phoenix multi-head (2026) 36 relative score; Balanced multi-head post: Heuristic ranker (2023 shape) 62, Phoenix multi-head (2026) 88 relative score; Dwell-driving long-form: Heuristic ranker (2023 shape) 44, Phoenix multi-head (2026) 81 relative score; Generic AI reply: Heuristic ranker (2023 shape) 38, Phoenix multi-head (2026) 18 relative score

Same number of impressions, very different scoring shape under the two rankers

The single-signal shape on the left rewards volume on the highest weighted signal. The multi-head shape on the right rewards posts that fire a wider mix of actions. That is the structural property anything optimised for "how do I get more likes" is now misaligned with.

Out of network is a different model entirely

The handful of accounts a viewer follows are not the For You feed anymore. They are one of twelve candidate sources, alongside three dedicated out of network retrieval sources (home-mixer/sources/phoenix_source.rs, home-mixer/sources/phoenix_moe_source.rs, home-mixer/sources/phoenix_topics_source.rs), ads, who-to-follow modules, prompts, push-to-home heroes, cached posts, and a tweet-mixer source. Three of the twelve sources are dedicated to posts from accounts the viewer does not follow.

Those three OON sources all call a two tower retrieval model. One tower embeds the viewer's history sequence. The other embeds candidate posts plus author signals. The retrieval step takes the dot product, returns the top K. Then a single multiplier, OON_WEIGHT_FACTOR in home-mixer/scorers/oon_scorer.rs, rescales those candidates against the in network ones before final ranking.

The piece worth saying out loud: getting into a stranger's feed in 2026 is a question about your post's embedding, not your engagement metrics. The two tower retrieval does not see your likes count when it picks you. It sees how close your candidate embedding sits to the viewer's history embedding. Generic engagement bait sits in the dense centre of the embedding space, alongside everything else trained on the same internet. Voice-distinctive copy lives further out. The OON retrieval is where that distance pays off, and it is the largest single growth surface most creators have on X right now. A3 of this series walks the two tower math and the playbook for getting embedded-distinctive copy past the dot product.

Why "algorithm hacks" stopped working

The 2023 ranker was a feature-engineering problem. Every "X algorithm hack" you ever read, the question-as-hook, the 280-char limit gambit, the reply-magnet first line, the dwell-time bait, the screenshot-of-text move, worked because each one mapped onto a specific feature the heavy ranker consumed. Optimize for the feature, win the slot.

The 2026 ranker has no features in that sense. Every hand engineered feature was eliminated. Phoenix learns its own representation of what a "reply-magnet first line" looks like from the millions of viewer histories in training data. That representation is then conditioned on the specific viewer, because every score is conditioned on their history sequence. The hack that worked in 2023 because it tickled a single feature representation now competes against a per-viewer learned model of "what kind of post does this person actually engage with." If that person's engagement pattern is biased toward thoughtful long-form replies, your screenshot-of-text move scores worse for them, even if it scored well for a generic 2023 audience.

The diversity layer compounds this. After Phoenix ranks the candidates, home-mixer/scorers/author_diversity_scorer.rs walks the list and multiplies repeated-author scores by an exponential decay factor. Your second post in a feed gets multiplied by decay. Your third by decay². By the seventh post in a session, the multiplier is near the diversity floor, regardless of how good Phoenix said your individual score was. home-mixer/scorers/vm_ranker.rs's Determinantal Point Process reranker layers an additional diversity-aware selection on top of that for the highest-prominence slots. The volume playbook ("post 10 times a day, optimize for impressions") is now structurally penalised. A7 quantifies the decay curve and gives the cadence playbook that respects it.

The summary version: hacks worked because the system rewarded surface patterns. The system now rewards a learned model of "what this specific viewer responds to," diversified across the top of feed. Surface patterns get crushed by both layers.

Voice as a history embedding

Here is the property of Phoenix that most algorithm coverage has missed. The viewer's history sequence is a chronologically ordered tape of past posts and the action the viewer took on each. Every creator the viewer has historically engaged with appears in that sequence multiple times: their posts as token embeddings, paired with the actions the viewer took.

The transformer learns, implicitly, what posts from you look like in that viewer's history. Not your username (that is just one hashed token in a 1M-author vocabulary). Your distribution. The pattern of opinions, sentence structures, framing moves, recurring themes. The viewer's attention head can latch onto that pattern across the sequence. When a new candidate from you arrives, the model has a per-viewer prior on "this is one of those posts."

Voice consistency directly increases the strength of that prior. Voice drift weakens it. The collapse is per-viewer (every follower has a different history), but it is consistent in direction: the more your recent posts look unlike your historical posts in that viewer's history, the less the model can leverage the prior. The score gets pulled toward the cold-start baseline for that viewer.

The candidate-isolation mask compounds the effect. Because candidates cannot attend to each other, one viral post in your recent history does not rescue an off-voice post that ships afterward. Each candidate is scored on its own merits against the viewer's history pattern. A streak of three on-voice posts followed by one off-voice post does not average out. The off-voice post is scored, in isolation, against a viewer who remembers your historical pattern.

This is the structural argument for voice as a moat, and it is now an algorithm-level argument. Not a brand-level one, not a "your audience will notice" one, but a "the ranker assigns it lower probability because it does not match the embedding pattern in viewer history" one. A8 of this series walks the embedding math in depth and gives the mechanical definition of voice fidelity in Phoenix-native terms.

What this means for tools built on the old assumption

Three of the major AI writers in this category, Tweet Hunter, Typefully, Hypefury, were built when the ranker was a feature-engineering problem. Their templates, viral hooks, scheduled-thread patterns, and engagement optimizers are calibrated to that world. Tweet Hunter ships viral-tweet templates because in 2023 viral templates fired the retweet weight and won slots. Hypefury automates posting cadence because volume mapped to impressions. Typefully optimizes thread composition for in-network engagement because in-network was the dominant retrieval lane.

None of those bets survives the rewrite cleanly. Viral templates produce generic-engagement embeddings that lose the OON dot product to voice-distinctive copy. Posting cadence runs straight into the diversity decay. In-network optimization ignores three of twelve candidate sources.

VoiceMoat was built on the assumption that the ranker would move in this direction (we wrote the product roadmap against learned representations, not against feature engineering). audenAI, the writing-pattern model inside VoiceMoat, trains per user on 100 to 200 content pieces (posts, replies, threads, attached images) across 10 signals: tone, vocabulary, hook style, pacing, formatting, quirks, persona, authority, topic surface, and register. The 10-signal stack is the input to a per-user voice fingerprint that scores every draft against that user's actual distribution. That output is the operational definition of "does this look like one of your posts in your followers' history sequences." The full competitor breakdown, scored against six 2026-algorithm criteria, lives in A10 of this series.

The nine articles after this one

This piece is the cornerstone. Nine more articles unpack the specific mechanics. They publish over the next several weeks.

Every article in the series cites the repo file paths each claim rests on, labels inferred claims as inferred, and treats the 2023 leaked weights as directional reference only. If a claim is "widely believed but not in the repo," we say so. The point of writing all of this is not to be the loudest voice in algorithm coverage. It is to be the most accurate one, because the strategic conclusion ("voice is the moat") is only as strong as the technical foundation underneath it. The technical foundation is in the repo. We have read it. The next nine pieces unpack what is in there.

Frequently asked questions

Frequently asked questions

Is the May 2026 X algorithm the same as the 2023 Twitter algorithm?

No. The xai-org/x-algorithm repo released in May 2026 is a complete rewrite, not a re-host. The README states every hand-engineered feature was eliminated. The 2023 stack (MaskNet heavy ranker, SimClusters, TwHIN, RealGraph) has been retired and replaced by a single Grok-derived transformer called Phoenix.

What is Phoenix in the X algorithm?

Phoenix is the transformer that now ranks posts on X. It predicts 19 separate engagement actions per candidate, conditioned on the viewer's history sequence, and uses a candidate-isolation attention mask so candidates are scored against your history rather than against each other. Retrieval uses a separate two-tower model and the orchestration is written in Rust.

Why does voice consistency matter more under the 2026 X algorithm?

Because every post from a creator is scored independently against the viewer's per-creator history pattern. Consistent voice compounds that prior across your whole follower base, while voice drift weakens scoring for all your posts, not just the one that drifted. This is an inferred implication of the documented architecture.

Are the exact X ranking weights public?

No. The 19 head weights are redacted and the params module is excluded from the open-source release. The 2023 leaked weights (like x0.5, reply x13.5 to 27, dwell x0.0001) are directional reference only, not authoritative for the 2026 stack.

AI disclosure

AI disclosure

This article was drafted with AI assistance and human-edited by Prateek Singh. All technical claims are sourced to the xai-org/x-algorithm repository; file paths are cited inline.

More in the series

X Algorithm

How Phoenix ranks every post: a creator's guide to the 19 engagement heads

X.AI's open-sourced Phoenix model does not score posts on a single "engagement" number. It predicts 19 separate user actions in parallel, each paired with a WEIGHT constant in home-mixer/scorers/weighted_scorer.rs (FAVORITE_WEIGHT, REPLY_WEIGHT, and 17 more): favorites, replies, quotes, reposts, photo expands, clicks, profile clicks, video quality views, three share variants, two dwell variants, follow-author, plus four negative actions and an implicit not-dwelled signal. A final weighted sum decides feed position. This article walks each head from the phoenix/run_pipeline.py source: which UI gesture trains it, which weight it pairs with, and what content patterns light it up. By the end, a creator understands why a post that gets 500 likes can rank below one with 80 likes and a 12-second dwell. We close with a quick framework for designing posts that fire multiple heads, not one.

16 min read

·

·

X Algorithm

The negative-signal economy: how one mute outweighs 50 likes on X

NEGATIVE_SCORES_OFFSET and NOT_INTERESTED_WEIGHT are why the 2026 X ranker's math is subtractive, not additive. Net-negative posts get pushed through a separate score-offset branch in weighted_scorer.rs where the combined score is rescaled as (combined + NEGATIVE_WEIGHTS_SUM) / WEIGHTS_SUM × NEGATIVE_SCORES_OFFSET, so one predicted mute or not-interested overwhelms dozens of predicted likes. This article traces every negative signal: the four explicit weight terms, the implicit not_dwelled_score, the four hard-kill filters that run upstream of any scoring, and the off-voice-drift to mute pipeline. We close with a creator-specific section: what content patterns trigger followers to mute, why voice drift is the single biggest negative-signal driver, and how to detect drift before publish.

13 min read

·

·

X Algorithm

Your voice is an embedding: how Phoenix encodes creator identity

Phoenix does not "see" your account as a username. It sees you as a hashed author ID combined with a post embedding, projected into a learned space. Every viewer who has interacted with you has a history sequence that contains those projections, paired with the action they took. When Phoenix scores any new candidate from you, the candidate-isolation mask lets that candidate attend to the viewer's full history but not to the other candidates in the batch. Net effect: your voice is encoded in two places: the author embedding itself, learned at training time, and the distribution of your posts in viewers' history sequences. Drift either of those and the model's prediction of you collapses. This article makes the math intuitive for a non-ML creator, and explains exactly what "voice fidelity" means in Phoenix-native terms: tight distribution in the post-embedding space, anchored by a stable author embedding.

17 min read

·

·

X Algorithm

Out of network is the new in-network: how Phoenix retrieval surfaces unfollowed creators

Three of the twelve home-mixer sources are dedicated to surfacing posts from accounts the viewer does not follow: phoenix_source.rs (general OON retrieval), phoenix_moe_source.rs (mixture-of-experts variant), and phoenix_topics_source.rs (topic-keyed retrieval). All three call a two-tower model that embeds user history and candidate posts into a shared space and returns the top-K via dot product. A single OON_WEIGHT_FACTOR in oon_scorer.rs rescales those candidates against in-network ones for the final blend. This article explains the two-tower math, why OON is no longer a small fraction of the feed, and how a creator gets surfaced to non-followers. We finish with a concrete playbook: write embedding-distinctive copy, not generic engagement copy. The OON retrieval lane is the largest single growth surface a creator has on X in 2026.

13 min read

·

·

X Algorithm

Why X feeds reject your third post of the day: author diversity and DPP

The home-mixer applies two diversity passes that no creator-facing article has explained. First, author_diversity_scorer.rs sorts candidates by weighted score, then walks the list applying an exponential decay multiplier per author occurrence: (1 - floor) * decay^position + floor. The first post from a creator gets the full score; the second gets decay; the third gets decay²; fast approaching floor. Second, vm_ranker.rs applies a Determinantal Point Process rerank at the top of feed when theta > 0, explicitly maximizing diversity-adjusted score across the visible top-max_selected_rank slots. Combined: a creator who posts 10 times a day has 7 of those posts hard-capped near the diversity floor. This article quantifies the decay curve, explains DPP in plain language, and rewrites the "how often to post" question into the right shape: post fewer times, with higher per-post voice distinctiveness.

12 min read

·

·

X Algorithm

VoiceMoat vs Tweet Hunter, Typefully, Hypefury: which one writes for the 2026 algorithm

Three of the major AI tweet writers were built when the X ranker was a heuristic-plus-GBDT pipeline scoring each post on a single weighted scalar. Their templates, viral hooks, and engagement maximizers are calibrated to that world. In May 2026, X.AI open-sourced a Grok-derived transformer ranker that scores 19 separate engagement heads, applies negative-signal weights of equal magnitude, isolates candidates from each other in the attention mask, and conditions every score on the viewer's history sequence. The new moat is voice consistency across that history sequence, because consistency compounds per-creator across all 19 heads while drift triggers mute and not-interested with asymmetric penalty. This article compares Tweet Hunter, Typefully, Hypefury, and VoiceMoat against six 2026-algorithm criteria. The conclusion is structural, not feature-list: only one of the four is built on the voice-fidelity assumption the new algorithm rewards.

13 min read

·

·

The whole series

The X algorithm in May 2026: all ten articles

Read ›

Read ›

[

ready to start?

]

Create more.
Stay unmistakably you.
Grow from there.

3-day trial from $1 · Cancel anytime · Your writing stays private

[

ready to start?

]

Create more.
Stay unmistakably you.
Grow from there.

3-day trial from $1 · Cancel anytime · Your writing stays private

[

ready to start?

]

Create more.
Stay unmistakably you.
Grow from there.

3-day trial from $1 · Cancel anytime · Your writing stays private