Why do two users get different variations?
Last updated:
In a percentage rollout that is the expected behavior. Each user is hashed together with the flag's salt to produce a bucket from 0 to 99, so a 30% rollout puts roughly three users in ten on the new variation. The same user always lands in the same bucket for the same flag. Hashing is per flag, so being inside the 30% for one tells you nothing about any other.
Two colleagues compare screens, see something different, and file a bug. The rollout is almost always working exactly as configured.
What the split is doing
The user identifier and a stable per-flag salt are hashed together, producing a number from 0 to 99. A 30% rollout serves the new variation to everyone below 30. Because the hash is deterministic, a user stays in the same bucket forever, across refreshes, sessions and devices.
Which is the behavior you want, since nobody should be watching a feature appear and vanish between page loads.
Why your test accounts disagree
They hash differently. There is no pattern to it, and no way to reason about which side a given account will land on without checking.
Give yourself a deterministic answer instead: add a targeting rule above the rollout that serves your own account the variation you want to see. Rules run first and win, so the rollout never gets a say.
1. email endsWith "@yourcompany.com" -> serve true2. Fallthrough: 30% rolloutNow internal accounts always see the new path and the percentage still governs everyone else.
Why the same user differs across two flags
Different flags produce different hashes for the same person. If they did not, every rollout at the same percentage would hit exactly the same users, and a customer unlucky enough to sit at bucket 2 would be the guinea pig for everything you ship.
Independent hashing spreads that risk. It also means you cannot line up two rollouts by setting both to 30%.
When it really is wrong
There are still two cases where the complaint is real.
No identifier. Without a stable key there is nothing to hash, so the rollout skips that caller. They get the next matching rule or the default variation instead, and they stay outside the split however high you set the percentage. That case has its own answer.
A changing identifier. If you pass a session ID rather than a user ID, the bucket moves whenever the session rotates. Anything you hash on has to outlive the rollout.
Widening the rollout
Going from 30% to 50% widens the window. Everyone already inside stays inside, and only new users are added, so nobody loses a feature they had yesterday.
If you want the hash itself rather than its consequences, Rollout strategies sets out the mechanics.
Related questions
Do I need a user ID to evaluate a feature flag?
Only for percentage rollouts. Without a stable identifier the rollout skips that caller, who gets the next matching rule or the default variation.
Why did my targeting rule not match?
Rules run top to bottom and the first match wins, so an earlier rule can shadow the one you are testing. The other usual cause is a missing context attribute.
Why does my flag work in dev but not production?
Flags are configured per environment, so enabling one in development changes nothing elsewhere. Rules and rollout percentages are per environment too.
Still stuck?
The docs cover every SDK, and the Free plan is enough to reproduce most of these locally.