Skip to main content
Percentage rollouts let you expose a feature to a controlled slice of your user base. Rather than flipping a flag on for everyone at once, you can start at 5%, verify behaviour, then increase gradually to 100%. Common use cases include:
  • Gradual releases — Limit blast radius when shipping risky changes
  • A/B tests — Split users between two variants and measure impact
  • Canary deployments — Roll out to a small group before a full release

How bucketing works

When a percentage rule is evaluated, Togul hashes the value of the bucket_by field from the evaluation context (default: user_id) combined with the flag’s auto-generated salt. This produces a deterministic bucket assignment in the range 0–100. If the computed bucket falls within rollout_percentage, the rule matches and return_value is returned. Otherwise, evaluation continues to the next rule. The same user always gets the same result for the same flag. The hash is stable across requests, servers, and restarts as long as the flag’s salt and the bucket_by value remain unchanged.

The bucket_by field

By default, bucket_by is user_id. You can set it to any string key present in the evaluation context — for example, account_id or session_id.
Use a stable identifier. Avoid fields like session_id that change between sessions, or users will get inconsistent results across requests.

Creating a percentage rule

Send a POST request to /api/v1/projects/{project_id}/rules with rule_type set to percentage.
curl -X POST http://localhost:8080/api/v1/projects/$PROJECT_ID/rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "flag_id": "550e8400-e29b-41d4-a716-446655440000",
    "priority": 1,
    "rule_type": "percentage",
    "rollout_percentage": 10,
    "bucket_by": "user_id",
    "return_value": true
  }'
The rollout_percentage field accepts an integer from 0 to 100. Response:
{
  "rule": {
    "id": "rule-uuid-here",
    "flag_id": "550e8400-e29b-41d4-a716-446655440000",
    "priority": 1,
    "rule_type": "percentage",
    "rollout_percentage": 10,
    "bucket_by": "user_id",
    "return_value": true,
    "is_active": true,
    "created_at": "2024-03-15T10:00:00Z",
    "updated_at": "2024-03-15T10:00:00Z"
  }
}

Updating the rollout percentage

Increase or decrease the percentage at any time using PATCH /api/v1/projects/{project_id}/rules/{id}.
# Increase to 50%
curl -X PATCH http://localhost:8080/api/v1/projects/$PROJECT_ID/rules/$RULE_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rollout_percentage": 50}'

# Roll out to 100%
curl -X PATCH http://localhost:8080/api/v1/projects/$PROJECT_ID/rules/$RULE_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rollout_percentage": 100}'

Full example: 10% → 50% → 100%

1

Create a 10% rollout rule

Start with a small percentage to validate there are no issues.
curl -X POST http://localhost:8080/api/v1/projects/$PROJECT_ID/rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "flag_id": "550e8400-e29b-41d4-a716-446655440000",
    "priority": 1,
    "rule_type": "percentage",
    "rollout_percentage": 10,
    "bucket_by": "user_id",
    "return_value": true
  }'
Save the rule.id from the response.
RULE_ID="rule-uuid-here"
2

Increase to 50%

After verifying metrics and error rates, expand the rollout.
curl -X PATCH http://localhost:8080/api/v1/projects/$PROJECT_ID/rules/$RULE_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rollout_percentage": 50}'
3

Roll out to 100%

Once you’re confident, complete the rollout.
curl -X PATCH http://localhost:8080/api/v1/projects/$PROJECT_ID/rules/$RULE_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rollout_percentage": 100}'
At this point you can simplify by setting the flag’s default_value to true and removing the rule, or leave the rule in place.

Multiple percentage rules

You can create multiple percentage rules on the same flag with different priority values and different return_value settings. Rules are evaluated in priority order (lowest number first), so the first matching bucket wins. For example, to assign variant A to 20% of users and variant B to another 20%:
  • Rule with priority 1, rollout_percentage: 20, return_value: true (variant A)
  • Rule with priority 2, rollout_percentage: 20, return_value: false (variant B)
Because buckets are computed independently for each rule, users in the second rule’s 20% are a different set from the first rule’s 20%.

Best practices

  • Use a stable identifier. user_id is a good default. Avoid transient values like session_id.
  • Start small. Begin at 5–10% and increase only after validating metrics.
  • Do not change bucket_by after launch. Changing it reassigns all users to different buckets.
  • Monitor last_used_at on your API key to confirm evaluation traffic is flowing as expected.

Build docs developers (and LLMs) love