Assignment is hashing, not coin flips
The naive image of random assignment, flip a coin when the user arrives, store the result, fails several requirements at once: it needs a write on every first exposure, a lookup on every subsequent one, and it cannot be reproduced after a data loss or across systems.
Production assignment is deterministic hashing. Concatenate a stable user identifier with the experiment's identifier and a salt, hash it, and map the hash into buckets: perhaps a thousand of them, allocated to arms in the configured proportions.
The properties this buys:
- Stateless and reproducible. Any service, any time, computes the same assignment from the same inputs, no assignment database required.
- Consistent. The user lands in the same arm on every visit, on every device that shares the identifier.
- Independent across experiments. The experiment id inside the hash decorrelates assignments, so being in treatment for experiment A says nothing about arm membership in experiment B, which is what allows hundreds of experiments to overlap on the same traffic.
Gotcha: the salt is load-bearing. Reusing an old experiment's salt reproduces its assignment exactly, delivering a treatment group pre-marinated in a previous treatment's effects. Salts are minted fresh per experiment, and the discipline is boring precisely until the day it was skipped.

