🪣 Custom Bucketing
Overview
When it comes to splitting the affectation of a flag, the targetingKey is usually given a user ID. This key ensures that a user will always be in the same group for each flag.
But sometimes we want to be sure that a group of users will always be in the same group for each flag.
The bucketingKey field in the flag configuration allows you to define a different identifier to be used instead of the targetingKey.
This enables you to split users based on a custom identifier, such as a team ID, a company ID, or any other attribute that is common to multiple users.
How it works
When evaluating flags, the targetingKey is used to build the hash that will allow GO Feature Flag to affect the user to a variation, if a bucketingKey is defined, it will be used instead of the targetingKey.
Since we are using an attribute that is common to multiple users at the same time, we can ensure that all users with the same attribute will always be in the same group.
- If a value in the corresponding
bucketingKeyis not found in the evaluation context, the flag rules will not be evaluated, and the SDK will return the default value. - Since the
bucketingKeyis not unique to a user, you can end up with a not uniform distribution of users in the variations depending on the repartition of thebucketingKeyvalues. - The bucketing key must be a string.
Example: Split users based on their team ID
Let's say you want to rollout a new feature and be sure that all the members of the same team will receive the same variation.
To achieve this, you can define the bucketingKey to be the teamId in the flag configuration.
scream-level-feature:
bucketingKey: "teamId"
variations:
low: "whisper"
medium: "talk"
high: "scream"
defaultRule:
percentage:
medium: 50
high: 50
With this flag configuration, the teamId value will be used for hashing instead of targetingKey. The value must be provided to the evaluation context:
evalCtx := openfeature.NewEvaluationContext(
"user-123",
map[string]interface{}{
"teamId", "f74b72",
},
)
boolValue, _ := client.BooleanValue("first-flag", false, evalCtx)
As a result, users who are members of the same team will receive the same flag variation, consistently.
A different bucketingKey can be used per experiment, though normally you'll only have a handful of possible values.
Example: Using nested properties for bucketing
GO Feature Flag supports dot notation for accessing nested properties in your evaluation context. This is particularly useful when your context has a hierarchical structure.
For instance, if you want to bucket users based on their company ID, which is nested inside a company object:
premium-feature:
bucketingKey: "company.id"
variations:
enabled: true
disabled: false
defaultRule:
percentage:
enabled: 20
disabled: 80
The evaluation context should include the nested structure:
evalCtx := openfeature.NewEvaluationContext(
"user-456",
map[string]interface{}{
"company": map[string]interface{}{
"id": "company-789",
"name": "GO Feature Flag",
"tier": "enterprise",
},
},
)
boolValue, _ := client.BooleanValue("premium-feature", false, evalCtx)
In this example, all users from the same company will receive the same feature variation because the bucketing is based on company.id.
You can use multiple levels of nesting, such as user.profile.role or organization.settings.region, allowing for flexible bucketing strategies based on your data structure.