Why does my reach swing so much post to post?
Because reach is the product of many independent variables, and several reset every time. Each post is retrieved for a different, partly-random set of feeds; competes against whatever else is live at that moment; is shown to viewers with different seen-histories and mutes; and rides early-engagement signals that compound. The released code has no per-post "consistency" — it scores each post fresh against a changing field. Variance isn't a glitch or a shadowban; it's the expected behavior of a system where the same post meets a different world each time.
You post two similar things; one gets 500 views, the next gets 50,000. The instinct is that something changed about you — a shadowban lifted, a penalty applied. Usually nothing about you changed. The released architecture explains the swing without any account-level switch.
Every post meets a different field
Reach is a chain of independent draws, and the code shows each link resetting per post:
| variable | why it changes every post |
|---|---|
| Who it's retrieved for | Phoenix out-of-network retrieval surfaces your post to a different candidate audience each time. |
| What it competes against | It's scored against whatever else is live in those feeds at that moment — a changing field. |
| Who's eligible to see it | The previously-seen and muted-keyword filters remove it for different viewers depending on their history and settings. |
| Early engagement | The scoring signals reward predicted engagement; a strong first hour compounds into more reach, a weak one doesn't. |
Before scoring, Home Mixer removes: duplicates, posts that failed metadata hydration, posts older than a threshold, your own posts, repost duplicates, paywalled content you can't access, posts you've already seen or been served, posts containing your muted keywords, and posts from authors you've blocked or muted.
The seen-filter alone creates variance
The previously-seen filter removes your post for anyone who already encountered it — using both client-sent seen IDs and a bloom filter. The set of "already saw it" viewers differs every time you post, so the eligible audience is never the same twice:
7// Filter out previously seen posts using a Bloom Filter and 8// the seen IDs sent in the request directly from the client
The PreviouslySeenPostsFilter removes candidates the viewer has already seen, using both the seen_ids sent by the client and bloom filters; matching posts are partitioned into 'removed'.
Out-of-network is where the big swings live
In-network reach (your followers via Thunder) is relatively stable — that audience changes
slowly. The volatility comes from out-of-network
discovery: whether Phoenix surfaces you to a large relevant audience this time, and whether you
clear the handicap, is where a post either catches or doesn't. Two similar posts can land on
opposite sides of that line.
Out-of-network candidates have their score multiplied by an OON_WEIGHT_FACTOR, with the code comment stating the intent: 'Prioritize in-network candidates over out-of-network candidates.' The factor's value is in the withheld params module.
What the code doesn't say
How much variance is "normal." The code explains the sources of swing but not a
distribution — there's no published number for expected post-to-post variance. Distinguishing
normal variance from a real penalty requires measuring your own baseline over many posts, which is
exactly the kind of judgment no single post can support.
The numeric values of the current weights are not included in the open-source release: weighted_scorer.rs references a params module (e.g. p::FAVORITE_WEIGHT, p::REPLY_WEIGHT) whose values are not present anywhere in the published repository.
What to do with this
Judge reach on trend, not single posts. One quiet post is noise; a sustained shift against your own baseline is signal. This is precisely why xDoctor scores against your trailing distribution rather than absolute numbers — it's built to tell ordinary variance apart from a genuine change in how you're being treated, which no individual post can reveal.