A/B testing platforms need to reliably split users between different experiment variants to ensure valid statistical results.
The splitting mechanism must be:
User splitting visualization
Hashing converts a user identifier (like user_id) into a numerical value that can be used for variant assignment.
user_id: "user123" → hash("user123") → 0.742
if (hashValue < 0.5) → Variant A else → Variant B
Common hash functions:
Same input always produces same output
Outputs are evenly spread across range
Low CPU overhead for high traffic
Salting ensures that different experiments don't assign the same users to variants in correlated ways.
hash("user123" + "experiment1") → 0.15
hash("user123" + "experiment2") → 0.82
Without salting, users might consistently land in the same variant across experiments, creating bias.
Ensures one experiment doesn't affect another's user distribution
Prevents users from always being in the same variant across tests
Maintains proper randomization for accurate results
After hashing, we need to map the hash value to specific variants with desired weights.
function assignVariant(userId, experimentId, weights) { // Combine user ID with experiment salt const salt = userId + experimentId; // Generate hash value between 0 and 1 const hashValue = hashFunction(salt) / MAX_HASH_VALUE; // Determine variant based on weights let cumulativeWeight = 0; for (const [variant, weight] of Object.entries(weights)) { cumulativeWeight += weight; if (hashValue < cumulativeWeight) { return variant; } } // Fallback to first variant return Object.keys(weights)[0]; }
When running multiple experiments that might interact, you need to ensure proper isolation between layers.
hash("user123" + "layer1" + "experimentA")
hash("user123" + "layer2" + "experimentB")
For some experiments, you might want to keep users in the same variant even if weights change.
Normal Assignment
Users may switch when weights change
Sticky Assignment
Users stay in original variant
You may want to limit what percentage of users enter an experiment at all.
See all the concepts working together in this complete simulation: