# Percentage rollouts

Assign a stable cohort and expand a release without reshuffling subjects.

A percentage condition hashes one context attribute into a deterministic bucket. The same value keeps
the same assignment while the flag, rule, attribute path, and normalized subject value stay stable.

Use percentages to expand a release predictably after narrow validation. They allocate traffic; they
do not measure experimental outcomes or replace application telemetry.

## Choose the rollout unit

Choose the identifier for the unit that must experience the release consistently.

| Desired consistency              | Attribute example                                             |
| -------------------------------- | ------------------------------------------------------------- |
| One person across sessions       | `user.id`                                                     |
| Everyone in one customer account | `account.id`                                                  |
| One installation or device       | Stable application-owned installation ID                      |
| One anonymous session only       | Durable session ID, when session-level movement is acceptable |

Use opaque, stable identifiers. Avoid timestamps, random values, emails, mutable display names, or
values regenerated on every request.

Nested paths such as `account.id` are valid. Missing paths miss the percentage condition and continue
to later rules or the fallback.

## Understand deterministic assignment

A 10% rule does not enable the first ten requests. It selects buckets based on the rollout attribute.
Repeated evaluations for the same subject remain in the same bucket.

Increasing from 10% to 20% retains the original cohort and admits more buckets. Decreasing removes
some of the most recently included allocation while preserving deterministic assignment.

Do not promise that a percentage equals a precise user count. Hash distribution approaches the target
across a sufficiently large population.

## Run a gradual expansion

For an account-level checkout release:

1. Keep the production fallback on the existing checkout.
2. Add an explicit internal account rule first.
3. Add `account.plan equals pro` and 5% by `account.id`.
4. Validate application health and business outcomes.
5. Increase to 10%, 25%, 50%, then 100% using the same rule and path.
6. Make the new checkout the fallback.
7. Remove the percentage and exception rules.

Each change should state its observation window, decision owner, and rollback condition. Pause by
leaving the allocation unchanged. Roll back by reducing or removing the rule.

## Avoid cohort reshuffling

These changes can move subjects between buckets:

- Changing `user.id` to `account.id`.
- Lowercasing or trimming identifiers differently.
- Replacing an identifier format during a migration.
- Deleting and rebuilding the rule with different identity inputs.
- Allowing different services to supply different values for the same path.

If the rollout unit must change, treat it as a new rollout. Return to a narrow cohort and validate the
new assignment rather than assuming continuity.

## Observe the rollout correctly

FeatureGate provides hosted request counts, errors, rate limits, and direct per-flag totals. Local
snapshot evaluations remain inside the application and are not exposure analytics.

Use application logs, metrics, traces, and business analytics to judge outcomes. Avoid logging full
evaluation context, resolved values, or raw customer identifiers.

## Complete and clean up

After 100% allocation, make the intended value the environment fallback. Remove the rollout rule and
observe the stable state before deleting the old application branch.

Archive the temporary flag only after callers no longer depend on it. A 100% rule is not a completed
cleanup; it still leaves runtime complexity and guarded code.

Related pages: [Run a controlled rollout](/docs/operate/controlled-rollout),
[Targeting rules](/docs/flags/targeting-rules), and
[Review and clean up flags](/docs/operate/review-and-clean-up-flags).
