Evaluation
Percentage Rollouts
How consistent hashing ensures deterministic percentage-based feature flag rollouts.
Percentage rollouts let you gradually release a feature to a fraction of users. The evaluation engine uses consistent hashing to ensure the same user always lands in the same bucket.
How it works
- When a rule has
operator: 'percent'andvalue: 50, it means "match 50% of users" - The engine hashes
userId:ruleIdto produce a number between 0-99 - If the hash result is less than the rule value (50), the rule matches
Hashing algorithm
The hash function uses a Java-style hashCode algorithm:
hash("userId:ruleId") → 32-bit integer → modulo 100 → 0-99The key properties:
- Deterministic — same
userId+ruleIdalways produces the same hash - Consistent — if a user is in the 30% bucket, they'll still be in the 50% bucket when you increase the rollout
- Independent per rule — a user may be in the 50% for one rule but not another, since the
ruleIdis part of the hash input
Example
A flag with a 25% rollout rule:
| Attribute | Operator | Value | Return Value |
|---|---|---|---|
| — | percent | 25 | true |
// User A: hash("user-a:rule-1") % 100 = 17 → 17 < 25 → matches
// User B: hash("user-b:rule-1") % 100 = 63 → 63 < 25 → does not match
// User C: hash("user-c:rule-1") % 100 = 8 → 8 < 25 → matchesIf you later increase the value to 75:
- User A (17) still matches
- User C (8) still matches
- User B (63) now matches too
Users who were already included stay included as you ramp up.
Requirements
The percent operator requires userId in the evaluation context. If userId is missing, the rule does not match.
// ✓ Has userId — percentage rules can match
await client.getFlag('new-feature', { userId: 'user-123' })
// ✗ No userId — percentage rules are skipped
await client.getFlag('new-feature', { email: 'jane@acme.com' })Gradual rollout strategy
A common pattern for safe releases:
- Create a boolean flag with a
percentrule at 5% - Monitor for errors or regressions
- Increase to 25%, then 50%, then 100%
- Once stable at 100%, remove the rule and keep the flag enabled (or remove the flag entirely)
Each increase is additive — all previously included users stay included.