Variations and Assignment
How users are assigned to variations
Section titled “How users are assigned to variations”When GrowthBook runs an experiment it needs to split users consistently across variations. It does this through a deterministic hashing process driven by two configuration values: the hashAttribute and the traffic coverage/split.
The hashAttribute
Section titled “The hashAttribute”The hashAttribute is the user property GrowthBook uses as input to the hash function. It is typically a stable identifier such as a user ID or a device ID. GrowthBook reads this value from the attributes object you pass to the SDK.
const gb = new GrowthBook({ apiHost: 'https://cdn.growthbook.io', clientKey: 'sdk-YOUR_KEY', attributes: { id: 'user-123', // hashAttribute value country: 'US', },});When the SDK evaluates an experiment it hashes hashAttribute + experiment.key together to produce a number between 0 and 1. This number determines which variation the user sees.
Deterministic hashing
Section titled “Deterministic hashing”GrowthBook uses the Fowler–Noll–Vo (FNV) hash algorithm. Given the same input string the hash always produces the same output, so a user assigned to variation B will always be assigned to variation B — on every page load, every session, and every device that shares the same id.
Traffic coverage and split
Section titled “Traffic coverage and split”Two settings govern how traffic is distributed:
| Setting | What it controls |
|---|---|
| Coverage | Percentage of users who are included in the experiment at all (0–100%). Users outside coverage receive the control value. |
| Split | How included traffic is divided across variations (e.g. 50/50, 33/33/34). Splits must sum to 100%. |
A user with a hash value below the coverage threshold is bucketed into an experiment. Their exact variation is then determined by where their hash falls within the split ranges.
Consistent assignment
Section titled “Consistent assignment”Because the hash is computed from stable inputs (the attribute value and the experiment key), assignment is fully consistent:
- The same user always sees the same variation for the same experiment.
- Refreshing the page or reinitialising the SDK does not reshuffle assignments.
- You can safely cache or server-side render experiment outcomes without coordination.
Tracking exposures with trackingCallback
Section titled “Tracking exposures with trackingCallback”Knowing which variation a user saw is essential for calculating metric lifts. GrowthBook does not send analytics events automatically — you wire up a trackingCallback that fires whenever a user is assigned to an experiment variation.
The callback receives two arguments:
experiment— the experiment definition (includingexperiment.key).result— the assignment outcome (includingresult.variationIdandresult.value).
import { GrowthBook } from '@growthbook/growthbook';
const gb = new GrowthBook({
apiHost: 'https://cdn.growthbook.io',
clientKey: 'sdk-YOUR_KEY',
trackingCallback: (experiment, result) => {
// Send exposure event to your analytics
analytics.track('Experiment Viewed', {
experimentId: experiment.key,
variationId: result.variationId,
});
},
});
await gb.init({ timeout: 2000 });