The X Algorithm: What's Actually Known, and How to Test It on Your Own Account

10 min readSocialAPI Engineering

The X Algorithm: What's Actually Known, and How to Test It on Your Own Account

Every "X algorithm explained" article presents a confident list of ranking factors. ★Almost all of it is inference, and much of it is inference from a partial code release that's now years out of date.★

Nobody outside X knows the current ranking rules. What you can do is run a controlled test on your own account — and that answer beats a general one, because it's about your audience rather than an average.


What's genuinely established

A short list, because the honest list is short.

Engagement in the first hour matters disproportionately. Early interaction is a strong signal, which is why timing and being present to reply both help.

Replies weigh more than likes. Interactions that take effort count for more than passive ones. Quotes weigh more still — why the ratios matter.

Dwell time is a signal. How long someone stops on a post, not just whether they tapped something.

Negative signals exist and are heavy. Mutes, blocks, and "not interested" reduce distribution more than an equivalent number of likes increase it.

Recency decays fast. Most reach happens in the first few hours.

⚠️ ★What's not established — despite being repeated everywhere: exact weights, whether links are penalised, whether specific words are downranked, and whether any single format universally wins. These get asserted constantly with no way to verify them.★

The reliable move isn't reading another explainer — it's measuring your own account and letting the data settle it.


Why general advice fails

The algorithm is personalised. There isn't one ranking — there's a ranking per viewer, built from what that person has engaged with. Advice that ignores this is describing an average that applies to nobody in particular.

It changes. Anything written more than a few months ago describes a system that has since been adjusted.

And the biggest one: what works for a 500,000-follower account in one niche tells you very little about a 2,000-follower account in another.★ Different audiences, different competition for the same slot.


Running a controlled test instead

This is the part that actually pays. You can't see the ranking rules, but you can measure outcomes on your own account.

Pick one variable. Format is the easiest: text-only, single image, video, thread opener, link.

Hold everything else roughly constant. Same topic area, similar posting times, same rough length.

Collect enough per bucket. ★At least 5 posts per variant★ — fewer and you're reading noise.

Compare medians, not means. One viral post makes a mean useless.

import requests
from collections import defaultdict
from statistics import median

BASE = "https://api.socialapi.tech"
KEY  = "your_api_key"
HDRS = {"X-API-Key": KEY}

def fetch(username, pages=5):
    out, cursor = [], None
    for _ in range(pages):
        params = {"username": username, "limit": 100}
        if cursor:
            params["cursor"] = cursor
        r = requests.get(f"{BASE}/v1/user/last_tweets",
                         params=params, headers=HDRS, timeout=60)
        r.raise_for_status()
        b = r.json()
        if not b["data"]:
            break
        out.extend(b["data"])
        cursor = b.get("meta", {}).get("next_cursor")
        if not cursor:
            break
    return out

def shape(p):
    """Classify a post by format — one variable at a time."""
    if p.get("videos"):            return "video"
    if p.get("photos"):            return "image"
    if "http" in p.get("text", ""): return "link"
    if p.get("is_reply"):          return "reply"
    return "text"

def rate(p):
    v = p.get("view_count") or 0
    if not v:
        return None
    return (p.get("like_count", 0) + p.get("retweet_count", 0)
            + p.get("reply_count", 0) + p.get("quote_count", 0)) / v

def compare(username, min_sample=5):
    buckets = defaultdict(list)
    for p in fetch(username):
        r = rate(p)
        if r is not None:
            buckets[shape(p)].append(r)

    rows = [(k, median(v), len(v)) for k, v in buckets.items()
            if len(v) >= min_sample]          # ★refuse thin buckets★
    return sorted(rows, key=lambda x: -x[1])

for form, med, n in compare("yourhandle"):
    print(f"{form:<8} {med:>7.2%}  ({n} posts)")

Reading it honestly: if your top format and your bottom format are within a factor of two, format isn't your lever.★ (Media fields and reply flags come back with each post, so the classification costs no extra calls.) That's a real result, not a failed experiment — it means effort belongs elsewhere.

⚠️ What this can't isolate: you're not running a true A/B. Your topics, timing, and audience all shift over the period. Treat a consistent gap across dozens of posts as a signal, and a small gap as nothing.


"Resetting" the algorithm

A common search, and the premise is slightly off.

★You can't reset ranking. What you can reset are the signals feeding your recommendations.★

  • Following tab — the chronological feed of accounts you follow, no ranking involved. Swipe to it from For You.
  • "Not interested" on posts you don't want more of
  • Mute topics and words in Settings → Privacy and safety
  • Unfollow or mute accounts whose content dominates your feed

⚠️ These change what you see, not how your posts are distributed. People conflate the two constantly — if your reach dropped, that's a different diagnosis.


Embedding a feed on your site

The other intent behind "twitter feed" searches — and a genuinely different task.

The official embed widget is free, requires no key, and handles rendering. ★For displaying a timeline on a page, use it — building it yourself is more work for the same result.★

Building it yourself makes sense when you need to filter (only posts with images, only above an engagement threshold), merge several accounts, restyle beyond what the widget allows, or cache to avoid third-party scripts on your page.

# a filtered feed the official widget can't produce
posts = fetch("yourhandle", pages=1)
featured = [p for p in posts
            if (p.get("like_count") or 0) >= 50 and not p.get("is_reply")]

Cache the result.★ A site that calls an API on every page view wastes calls and slows the page. Fetch on a schedule, serve from your own store.


Questions people ask

How does the Twitter algorithm work? It ranks per viewer using engagement signals, recency, and dwell time. Exact weights aren't published, so any specific breakdown is inference.

What is the X algorithm in 2026? Same answer — the mechanism is broadly known, the weights aren't, and it changes.

Is the Twitter algorithm open source? A portion was published years ago. It's out of date and was never the whole system.

How do I beat the algorithm? Test on your own account rather than following general advice. What works varies by audience.

Does the algorithm punish links? Widely claimed, not established. ★Test it on your own account — compare median engagement with and without links.★

Do hashtags help or hurt reach? One or two are fine. Stuffing many reads as spam-shaped — hashtag measurement.

Does the first hour matter? Yes, early engagement is a strong signal. Being available to reply in that window helps.

Do replies count more than likes? Generally yes — higher-effort interactions weigh more. Quotes more still.

What are negative signals? Mutes, blocks, and "not interested". They reduce distribution more than likes increase it.

How do I reset the Twitter algorithm? You can't reset ranking, only the signals feeding your recommendations — Following tab, "not interested", muted topics.

How do I reset my Twitter feed? Switch to the Following tab for chronological, or mute topics and accounts crowding your For You.

What's the difference between For You and Following? For You is ranked and personalised. Following is chronological, showing only accounts you follow.

Can I make Twitter chronological by default? The app remembers your last tab in most versions. There's no permanent setting.

Why is my reach down? More often variance, a format change, or a follower purge than an algorithm change — how to test.

Did the algorithm change recently? It's adjusted continuously without announcement. A sudden shift on your account is more likely your own content changing.

Does posting frequency affect reach? Beyond a point you compete with yourself. Consistency matters more than volume.

What's the best time to post for the algorithm? Whatever your own data says — computing your own beats any published figure.

Does video get more reach? Often, but not universally. Test it — the code above compares formats on your account.

Do threads perform better? The opener carries the reach; later parts get a fraction. Measuring part 7 against part 1 tells you about attention decay, not quality.

Does editing a post hurt reach? No evidence either way. Editing is a subscriber feature with a time window.

Do polls boost engagement? They generate interactions cheaply, which is a signal. Whether that helps your specific account is testable.

How does the algorithm decide what I see? From your past engagement, accounts you follow, and what similar users engage with. Personalised, so no two feeds match.

Can I see why a post was recommended? Not in detail. Some posts show a brief reason; there's no full explanation.

Does the algorithm favour paid accounts? Subscriptions include some reach features. Whether that dominates ranking isn't published.

Does deleting old posts help reach? No evidence, and deletion is irreversible — what's recoverable.

What is dwell time? How long someone stays on a post. It's a signal, and it's why a post can perform well without many visible interactions.

How do I get on the For You page? There's no submission. Strong early engagement from your existing audience is what propagates a post further.

Does the algorithm suppress certain words? Claimed often, not established. Anything asserting a specific banned-word list is guessing.

How do I embed a Twitter feed on my website? The official embed widget, free and no key required. Build it yourself only if you need filtering or restyling.

Can I embed a filtered Twitter feed? Not with the official widget. That needs fetching posts yourself and filtering before rendering.

How do I get a Twitter RSS feed? X doesn't provide RSS. You'd generate one from fetched posts.

Can I display multiple accounts in one feed? Not with the official widget — merging accounts requires fetching them yourself.

How often should I refresh an embedded feed? Cache and refresh on a schedule. Calling an API on every page view is wasteful and slow.

Is there an official Twitter algorithm API? No. Ranking isn't exposed. You measure outcomes, not the mechanism.

How do I A/B test on Twitter? Not truly possible — you can't post identical content twice. Compare medians across format buckets over weeks.

How many posts do I need to test a format? At least five per variant, ideally more. Below that you're reading noise.

Does the algorithm treat replies differently? Replies compete within a thread on ranking rather than in timelines — how replies surface.

Why do some small accounts go viral? Strong early engagement relative to audience size propagates. It's ratio-driven, not follower-count-driven.


The short version

Don't trust algorithm explainers, including this one. ★The mechanism is broadly known; the weights aren't, and they change.★

Test on your own account. One variable, five-plus posts per variant, compare medians. A consistent gap across dozens of posts is a signal; anything smaller isn't.

For embedding, use the official widget unless you need filtering or multiple accounts.

Our API returns posts with engagement counts, media fields, and reply flags — enough to classify by format and compare medians in one pass. Read-only, flat price per call, no rate limit of your own to manage.

Related reading: measuring engagement properly · finding your own best posting time · testing for visibility restrictions · why quotes weigh more than replies.