x-algorithm
Applicationxai-org/x-algorithm
Python? Actually Rust-based algorithm that powers X's For You feed, ranking posts via ML.
Overview
X's open-sourced recommendation engine that selects and ranks posts for the For You timeline. It combines in-network and out-of-network candidates, filters content through visibility rules, and scores posts using transformer-based models. Includes model training, retrieval, and ranking components with transparency tooling.
README Preview
# X For You Feed Algorithm\n\nThis repository contains the core code that determines which posts a viewer sees in the **For You** feed on X. It combines in-network content (from accounts the viewer follows) with out-of-network content (discovered through ML-based retrieval and other mechanisms), filters content based on a variety of inputs, and ranks posts using a transformer model.\n\n## Table of Contents\n\n- [Notable Updates](#notable-updates)\n - [August 14th, 2026](#august-14th-2026)\n - [August 13th, 2026](#august-13th-2026)\n- [Overview](#overview)\n- [System Architecture](#system-architecture)\n - [Request Path](#request-path)\n - [Labeling Path](#labeling-path)\n- [Components](#components)\n- [How It Works](#how-it-works)\n - [Scoring and Ranking](#scoring-and-ranking)\n - [Filtering](#filtering)\n- [Experiments and Configuration](#experiments-and-configuration)\n- [What's not in this repo?](#whats-not-in-this-repo)\n- [Under the Hood Label Transparency Tool](#under-the-hood-label-transparency-tool)\n- [Key Design Decisions](#key-design-decisions)\n- [License](#license)\n\n---\n\n\n\n## Notable Updates\n\n### August 14th, 2026\n\nNotable updates:\n\n- **How weights work.** There's a common misconception about how weights related to actions (e.g. Like, Share, Block, Report, etc) work in ranking. The weights scale the predicted probabilities of such actions (or predicted continuous values, e.g. dwell time) — they do *not* scale the raw engagement counts, so e.g. it'd be incorrect to see that a report has 468 times higher weight than a like and conclude that e.g. "1 report cancels out 468 likes". The weights are a multiple on your own predicted probability of Liking, Reporting, etc, which is substantially driven by your own behavior. We've [added comments](home-mixer/params/param.rs) [to the code](home-mixer/scorers/ranking_scorer.rs) so that LLMs or people reading it are more likely to understand it correctly.\n- **Brazil 2026 Elections.** As [announced
FAQ (2)
TroubleshootingWhy does my verified X account show “Not verified yet” on the profile page?
This is typically a temporary verification-status/UI synchronization issue, not an actual loss of verification. In the reported case, the “About this account” section correctly showed “Verified since June 2026” and “Identity verified with an official ID,” while the profile card incorrectly displayed “Not verified yet.” The issue resolved itself without any account changes. Troubleshooting steps: 1) Check “About this account” to confirm your verification status. 2) Close and reopen the X iOS app. 3) Update to the latest app version. 4) Log out and back in. 5) Wait for the server/UI state to refresh. Do not repeat identity verification unless the “About this account” section also shows it as incomplete. If the mismatch persists, contact X Support.
TroubleshootingHow to fix concurrent like events causing duplicate posts and inflated in-network scores with Tokio and DashMap?
The race occurs because the shared Semaphore::new(1) is never acquired, while DashMap only locks individual shards for each operation. The read-deleted-check, post insert, and VecDeque updates are therefore not atomic. Immediate fix: acquire the semaphore before calling insert_posts() and hold it for the entire operation:
let permit = Arc::clone(&semaphore)
.acquire_owned()
.await
.expect("semaphore closed");
post_store_clone.insert_posts(batch).await?;
drop(permit);
This serializes all inserts and prevents duplicate TinyPost entries, but it can reduce throughput. For a finer-grained fix, add an external lock per post/author and perform the complete read-modify-write under that lock:
let lock = self.locks
.entry(author_id)
.or_insert_with(|| Arc::new(tokio::sync::Mutex::new(())))
.clone();
let _guard = lock.lock().await;
if self.deleted_posts.contains_key(&post_id) {
return Ok(());
}
if self.posts.contains_key(&post_id) {
return Ok(()); // duplicate event
}
self.posts.insert(post_id, Arc::new(compact_post));
self.original_posts_by_user
.entry(author_id)
.or_default()
.push_back(tiny_post);
Apply the same lock to mark_as_deleted(), and do not hold a DashMap shard guard while accessing another shard. Verify the fix by sending two identical like events concurrently and asserting that the author's VecDeque contains the post ID only once.