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 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. 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 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.

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 true
2. Fallthrough: 30% rollout

Now 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. 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.

If you want the hash itself rather than its consequences, Rollout strategies sets out the mechanics.

Still stuck?

The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.