Percentage Rollouts
Gradually release a feature to a growing percentage of your user base. Start at 5%, validate, then increase to 25%, 50%, and finally 100%.
Percentage rollouts let you gradually release a feature to a growing percentage of your user base. Start at 5%, validate, then increase to 25%, 50%, and finally 100%.
How Bucketing Works#
Abrova Flags uses deterministic hashing into 10,000 buckets to assign users. It is the same in the service and in every SDK, ensuring:
The same user always gets the same bucket for a given flag
Users are evenly spread across 10,000 buckets
A user at 10% for flag A might be at 73% for flag B
A client SDK and a server SDK put the same user id in the same bucket
Evaluation Formula#
bucket = deterministic hash of the user → 0 … 9999
if rolloutPercentage is 100: flag is ENABLED for everyone
if rolloutPercentage is 0: flag is DISABLED for everyone
if bucket < rolloutPercentage × 100:
flag is ENABLED for this user
else:
flag is DISABLED for this user (reason OUTSIDE_ROLLOUT)For example, if rollout is set to 30%, users with a bucket value 0-2999 will see the feature, while users with bucket 3000-9999 will not. Raising the percentage keeps everyone who already had the feature and adds new users.
Rollout Strategy#
A recommended gradual rollout strategy:
Validate with a small group. Monitor error rates and metrics.
Expand to more users. Check performance at scale.
Half your users. Final validation before full release.
Full rollout. Clean up the flag after stabilization.
Rollout percentage only applies when a flag is enabled. If the flag is toggled off, it is disabled for all users regardless of the rollout percentage.
Which Id Is Used#
A partial rollout (1% to 99%) needs an id to place the user in a bucket.
The user id you pass to identify() in a client SDK, or as userId in the context of a server SDK
The anonymous id. Client SDKs create one per install or browser, keep it on the device and send it with every request. On a server you pass anonymousId yourself
When a user signs in, bucketing switches from the anonymous id to the user id, so the result for a partial rollout can change at that moment
The flag is served off with reason NO_BUCKETING_ID. This only happens on a server when the context has neither userId nor anonymousId
// Client SDKs (React Native shown): set the user once, the SDK remembers it
await flags.identify('user-123');
const enabled = flags.isEnabled('new-checkout');
// Server SDKs: pass the id with every call
const enabled = flags.isEnabled('new-checkout', { userId: 'user-123' });
const forVisitor = flags.isEnabled('new-checkout', { anonymousId: visitorId });In SDK 0.1.x a user without a user id was treated as inside every rollout. From 0.2.0, signed-out users are bucketed by their anonymous id, so a 10% rollout reaches about 10% of them. The bucketing method also changed, so users were assigned to rollouts again once when you upgraded.