Bell Statistics

What is randomization in experiments?

Randomization is assigning each unit to a treatment group by chance rather than by choice. It makes the groups comparable on every characteristic at once, including ones nobody measured, which is what licenses a causal reading of the difference between them.

Also called
random assignment, randomisation, random allocation
Allon Korem

Written by Allon Korem

Chief Executive Officer

Last updated

In plain English

Randomization is the whole reason an experiment can say anything about cause. When you assign users by coin flip, the two groups end up statistically identical in every respect — device, tenure, country, intent, mood, and the fifty things you have never measured or thought of. Matching on observed characteristics can balance the ones you listed; only randomisation balances the ones you did not. So when outcomes differ by more than chance allows, the change is the only remaining explanation.

That is a stronger property than it sounds. Every non-experimental method — matching, regression adjustment, propensity score matching — controls for confounding variables you can name and measure, and is defenceless against the ones you cannot. Randomisation handles the unknown unknowns by construction, which is why it remains the only design that needs no argument about which variables were included.

In practice it fails in four ways, none of which announce themselves. The assignment can be applied at the wrong moment, so users are bucketed before they reach the surface being changed and the effect is diluted across people who never saw it — we take that apart in when allocation point and exposure point differ. It can be applied at the wrong unit, so one person straddles both arms across devices or sessions. The hashing can be biased, correlated with a previous test, or reset by a cookie policy. And the arms can be filtered differently after assignment — excluding bot traffic from one arm using a rule that fires more often in the other quietly re-introduces selection.

The routine check is a sample ratio mismatch test, and it should run on every experiment before anyone reads the result. If you asked for 50/50 and got 50.4/49.6 on two million users, that gap is far outside chance and the randomisation is broken somewhere. This check has an unusual property: it is sensitive to almost any pipeline fault at all — assignment, logging, filtering, redirects — which makes it the cheapest single diagnostic in experimentation.

Two refinements are worth knowing. Stratified assignment randomises within blocks — by country, platform, or a pre-period value of the metric — which guarantees balance on those specific dimensions instead of merely making it likely, and reduces variance at the same time. And when the unit that must be randomised is not the user, the design changes shape entirely: clusters for a marketplace where users interact, regions for a geo experiment where the treatment cannot be hidden, or time periods in a switchback where the same units alternate.

The formula

The mechanics are a hash, and the checks are two standard tests. What matters is what the hash is computed over and when.

Deterministic assignment
bucket = hash(unit_id + experiment_salt) mod 100

The experiment-specific salt is essential: without it, the same user lands in the same bucket in every test and effects from one contaminate the next.

What randomisation buys
E[Y(1) | assigned to treatment] = E[Y(1)]

Potential outcomes are independent of assignment, so the difference in group means is unbiased for the average treatment effect. This equality is the entire causal claim.

Sample ratio mismatch check
χ² = Σ (observed − expected)² / expected, df = k − 1

Flag below about p = 0.001. Use the chi-square test calculator and run it before reading any result.

Balance check on a covariate
t = (x̄₁ − x̄₂) / √( s₁²/n₁ + s₂²/n₂ )

On a pre-experiment covariate this should be non-significant. Testing many covariates re-introduces multiple comparisons, so treat it as a smell test rather than a gate.

Worked example

A test on a new checkout step is assigned when a user lands on the site, but only 18% of sessions ever reach checkout. The experiment runs to 400,000 sessions per arm. The true effect on users who see the new step is a 4% relative lift in completion.

Sessions per arm
400,000
Share reaching checkout
18%
True effect on exposed users
+4% relative
Diluted effect on all sessions
+0.72% relative
Power at the allocation point
≈ 12%
Power at the exposure point
≈ 74%

Analysed on everyone assigned, the test has roughly a 12% chance of detecting the effect. Analysed on the 18% who actually reached checkout, it has 74%.

The randomisation is perfectly sound in both analyses — what changed is which population it is being read over. Including 82% of users who could not possibly have been affected does not bias the estimate, it dilutes it, and dilution costs power exactly as if you had shrunk the effect. The fix is to trigger the analysis at the point of exposure: count only users who reached the checkout step, in both arms. The critical detail is that the trigger condition must be evaluated identically in control — you need to know which control users *would* have hit the step — which is why exposure logging has to be instrumented deliberately rather than inferred afterwards. Filtering the variant on "saw the new step" and the control on nothing is not a fix; it is how a valid randomisation gets thrown away.

Common misconceptions

Our groups look balanced on the metrics we checked, so randomisation worked.
Balance on measured covariates is reassuring but is not what randomisation is for — matching can achieve that. Its unique value is balancing the variables you never measured, which no check can confirm directly. The one diagnostic worth running is the sample ratio test, which detects the pipeline faults that break assignment in the first place.
Alternating users between arms is as good as randomising.
Systematic alternation is predictable, and predictable assignment can correlate with something real — arrival order tracks time of day, campaign bursts and bot traffic. It also makes the assignment guessable by anyone who wants to game it. Use a hash of a stable identifier with an experiment-specific salt.
We reused the same user buckets across experiments, which keeps things consistent.
It also carries the previous experiment's effects into the next one, so a user who won in test A is systematically in a particular arm of test B. Salt the hash per experiment, and if tests genuinely interact, run them in a design built for it rather than hoping the effects do not overlap.

Frequently asked questions

What should I randomise on — user, session or device?
The most stable identifier the change can be consistently applied to, which is usually a logged-in user ID and otherwise a persistent device identifier. Session-level assignment lets the same person see both experiences, which confuses them and mixes the arms. The unit also has to match the unit of analysis: randomising by user and analysing by session inflates significance, because sessions from one user are not independent observations.
Should I use stratified randomisation?
It helps most when the sample is small or when a known covariate strongly predicts the outcome — country, platform, or the user's own pre-period value of the metric. Randomising within those blocks guarantees balance on them rather than merely making it likely, and reduces variance as a side effect. At millions of users plain randomisation balances everything well enough that the extra machinery rarely earns its complexity.
What if I cannot randomise at the user level?
Change the unit rather than abandoning the design. Marketplaces and social products where users interact call for cluster randomisation on groups that do not overlap. Changes visible to everyone, like pricing or advertising, call for geographic randomisation. Where none of those work, the fall-back is an observational method with explicitly stated assumptions — and the honest framing is that you have traded a guarantee for an argument.

Related terms

  • A/B testing

    A randomised experiment on live traffic — and randomisation is the only part that makes it causal.

  • Confounding variable

    A common cause of both variables — the reason a strong, stable correlation can mean nothing.

  • Geo experiment

    Randomise regions instead of users — the way to test marketing that cannot be hidden from a person.

  • Null hypothesis

    The assumption every test argues against, and the reason you can never prove two things are the same.

  • Propensity score matching

    Pair like with like on the probability of being treated — and hope nothing important went unmeasured.

  • Sample ratio mismatch

    The split is wrong, so the randomisation is broken — the cheapest and most decisive check you can run.

  • Selection bias

    When who ends up in the data is not who you meant to study — and more data makes it worse.

Calculate it

  • Chi-square test

    Test a contingency table of counts for association — any number of rows and columns.

  • A/B test sample size

    Size a two-proportion experiment before you launch, then read the lift and its interval once it lands.

  • Two-sample t-test

    Compare the average of two independent groups — plan the sample size, then test the result.

Knowing the term is the easy part

Applying it to a live measurement problem is the part that goes wrong. If you are designing an experiment, reading a result you do not trust, or trying to work out what your marketing actually caused, that is the work we do.

References

  • Fisher, R. A. (1935). The Design of Experiments. Oliver and Boyd.
  • Imbens, G. W., & Rubin, D. B. (2015). Causal Inference for Statistics, Social, and Biomedical Sciences. Cambridge University Press.