Why do two users get different variations?
Last updated:
In a percentage rollout that is the expected behaviour. Each user is hashed together with the flag key to produce a bucket from 0 to 100, 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. Different flags hash independently, so being in the 30% for one says nothing about another.
Two colleagues compare screens, see different things, and file a bug. Nine times out of ten the rollout is working exactly as configured.
What the split is doing
The user identifier and the flag key are hashed together, producing a number from 0 to 100. 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.
That stability is the whole point. Nobody watches 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
Two cases are worth ruling out.
No identifier. Without a stable key there is nothing to hash. A server SDK evaluating locally falls back to the control variation, and the hosted endpoint spreads traffic with no stickiness at all, which does produce a user seeing different values on consecutive requests. 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.
Hashing and rollout mechanics are documented in Rollout strategies.
Related questions
Do I need a user ID to evaluate a feature flag?
Only for percentage rollouts. Without a stable identifier a server SDK serves the control variation, and the hosted endpoint spreads traffic with no stickiness.
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 Solo plan is enough to reproduce most of these locally.