Dev Tools

How to Plan a Feature Flag Rollout That Doesn't Flip-Flop Users in 2026

The one property every gradual rollout needs — and how a simple hash-based bucketing scheme guarantees it.

📅 Aug 12, 2026·⏱️ 5 min read·✍️ Cikal Studio Labs
🚩

The property nobody notices until it breaks

Gradual feature flag rollouts sound simple: pick a percentage, ramp it up over time, done. But there's one property that's easy to violate by accident and painful to debug once it happens — a user who was already inside the rollout at 20% should never suddenly find themselves outside it at 30%. If your bucketing logic gets this wrong, users experience the feature flickering on and off as the percentage changes, which is confusing at best and breaks any state the feature depends on at worst.

Why naive approaches fail

A tempting but wrong approach is generating a fresh random number for every rollout check: Math.random() < percentage / 100. This is non-deterministic — the same user gets a different answer on every page load, every request, every server instance. It also can't guarantee monotonicity at all, since there's no stable relationship between a user and any particular outcome.

A better naive approach assigns each user a random bucket once and stores it in a database. That works, but it requires persistent storage and a write for every user before you can evaluate the flag — overkill for most rollouts, and a source of consistency bugs across services that read the assignment at different times.

The deterministic hash approach

The standard solution used by real feature-flag platforms is a deterministic hash function. Take the user's stable identifier (a user ID, session ID, or account ID), hash it with a fast, well-distributed string hash, and reduce it modulo 100 to get a number from 0 to 99 — call this the user's "bucket." This computation requires no storage: given the same ID, it always produces the same bucket, on any server, any time.

Once each user has a fixed bucket, the rollout rule becomes trivial: a user is included when bucket < percentage. This single comparison is what delivers the monotonicity guarantee for free. If a user's bucket is 23, they're excluded at 20% (23 is not less than 20) but included at 24% and everything above (23 is less than 24, 25, 30, ... 100). The bucket never changes, and the threshold only ever gets easier to clear as percentage rises — so a user can only move from OUT to IN as you ramp up, never the reverse.

Choosing a hash function

You don't need cryptographic strength here — you need speed and a reasonably even distribution across buckets. FNV-1a and djb2 are both simple, fast, well-understood string hashes that distribute typical ID formats (UUIDs, numeric IDs, emails) evenly enough for rollout purposes. What actually matters is testing that your implementation is genuinely deterministic (same input, same output, every time) and reasonably uniform (no bucket wildly over- or under-represented across a realistic sample of IDs).

Planning the schedule itself

Separately from bucketing, the rollout schedule — how fast you move from 0% to 100% — is a judgment call based on risk. Even, linear steps (say, five steps of 20% each) work well for low-risk changes. A doubling strategy (1%, 2%, 4%, 8%, 16%...) front-loads caution: early exposure is tiny while you watch for critical issues, and later steps move faster once you're confident, since by then you've already validated the riskiest unknowns at small scale.

Verify before you rely on it

Whatever hash and bucketing scheme you build or borrow, it's worth explicitly verifying the monotonicity property against real sample IDs before trusting it in production — checking that a fixed ID's IN/OUT status only ever flips one direction as percentage climbs from 0 to 100 takes seconds and catches an entire category of rollout bugs before your users do.

Frequently Asked Questions

Is the hash function actually deterministic, or does it use randomness?

It's a genuine deterministic FNV-1a string hash — the same user ID always produces the exact same bucket value, with no randomness involved. You can re-enter the same ID any number of times and verify it yourself.

How does it guarantee a user isn't dropped from a rollout as the percentage increases?

Each ID gets one fixed bucket (0-99) from the hash, and inclusion is simply 'bucket < percentage'. Since the bucket never changes and the threshold only gets more permissive as percentage rises, a user can only move from excluded to included, never the reverse. The tool includes a live check that verifies this for whatever ID you enter, across 0% to 100%.

Is there a tool to plan a feature flag rollout schedule online?

Yes — Feature Flag Rollout Calculator generates a step-by-step schedule using even steps or a doubling strategy, and includes a bucketing tester to check individual user IDs. It's a one-time $6.49 purchase — no subscription, no account required.

What's the difference between the even-steps and doubling strategies?

Even steps divide the distance from your current to target percentage into equal-sized increments. Doubling starts small and roughly doubles each step (1%, 2%, 4%, 8%...), which is useful when you want minimal early exposure while validating a risky change before ramping up faster.

Does this connect to my actual feature-flag service?

No — it's a standalone planning and verification tool. It doesn't integrate with LaunchDarkly, Split, Unleash, or any other service; it helps you design and sanity-check a rollout strategy and bucketing logic before implementing or configuring it in your own system.