Experiment design and power

core 12 minexperimentationpowersample-sizeab-testing

Builds on:Hypothesis testing and p-values

The idea

Most "failed" A/B tests were lost before launch: they never had enough traffic to see the effect they were hunting. Power analysis is the pre-flight check that the experiment, as designed, can actually answer its question.

The vocabulary, in one frame: choose α\alpha (false positive tolerance, usually 0.05) and target power 1−β1 - \beta (probability of detecting a real effect, usually 80%). Then for a true difference δ\delta between arms:

power rises asδSEdiffrises,whereSEdiff≈2σ2n.\begin{aligned} \text{power rises as}\quad &\frac{\delta}{\text{SE}_{\text{diff}}}\quad \text{rises}, \\ \text{where}\quad &\text{SE}_{\text{diff}} \approx \sqrt{\frac{2\sigma^2}{n}}. \end{aligned}

Setting the detection requirement gives the two master formulas. Sample size per arm to detect δ\delta:

n=(z1−α/2+z1−β)2⋅2σ2δ2n = \frac{(z_{1-\alpha/2} + z_{1-\beta})^2 \cdot 2\sigma^2}{\delta^2}

With the standard conventions, (1.96+0.84)2≈7.85≈8(1.96 + 0.84)^2 \approx 7.85 \approx 8, so:

n≈16 σ2δ2per arm (the rule of sixteen)n \approx \frac{16\,\sigma^2}{\delta^2} \quad \text{per arm (the rule of sixteen)}

Inverting gives the minimum detectable effect at a fixed nn:

MDE=(z1−α/2+z1−β)2σ2n≈2.8 σ2n.\text{MDE} = (z_{1-\alpha/2}+z_{1-\beta})\sqrt{\frac{2\sigma^2}{n}} \approx 2.8\,\sigma\sqrt{\frac{2}{n}}.

For a conversion metric, σ2=p(1−p)\sigma^2=p(1-p).

The economics live in the exponents: nn scales linearly in variance but with the inverse square of the effect size. Halving the MDE quadruples the required traffic — which is why "let's also detect tiny effects" quietly turns a two-week test into a two-quarter one, and why variance reduction techniques (CUPED, binary instead of continuous metrics, winsorizing whales) are worth real engineering effort: cutting σ2\sigma^2 by 30% cuts traffic requirements by 30%.

MDE is a business input, not a statistical output: it is the smallest lift that would justify shipping. Deciding it after seeing results is how teams talk themselves into noise.

Worked example

Checkout redesign. Baseline conversion p1=0.10p_1 = 0.10; the smallest lift worth the engineering cost is one absolute point, p2=0.11p_2 = 0.11. Standard α=0.05\alpha = 0.05 (two-sided), 80% power.

n=(1.96+0.84)2[ p1(1−p1)+p2(1−p2) ](p2−p1)2=7.85×(0.0900+0.0979)0.0001≈14,700 per arm.\begin{aligned} n &= \frac{(1.96 + 0.84)^2 \left[\,p_1(1-p_1) + p_2(1-p_2)\,\right]}{(p_2 - p_1)^2} \\ &= \frac{7.85 \times (0.0900 + 0.0979)}{0.0001} \\ &\approx 14{,}700 \text{ per arm}. \end{aligned}

Sanity check with the rule of sixteen using pˉ=0.105\bar{p} = 0.105: 16×0.105×0.895/0.0001≈15,00016 \times 0.105 \times 0.895 / 0.0001 \approx 15{,}000 — same answer to within rounding.

Convert to calendar time: 10,000 eligible users/day, split 50/50 → 5,000 per arm per day → sample complete in ~3 days. Run two full weeks anyway: weekday/weekend mix, weekly seasonality, novelty decay. Sample size is a floor, not a stopping rule.

Now the negotiation table — required nn per arm at this baseline:

Target MDE (abs.)nn per armDays of traffic at 10k/dayRealistic duration
2.0 points~3,800under 1 day1 full week anyway
1.0 point~14,700~3 days1-2 weeks
0.5 points~58,000~12 days2-3 weeks
0.2 points~356,000~71 daysa full quarter — renegotiate

That last row is the conversation that matters: for a 0.2-point MDE you do not just "run longer" — a quarter-long test blocks the roadmap and drifts with seasonality. You change the design: a more sensitive proxy metric, CUPED, or accept a larger MDE.

Cheat sheet

LeverEffect on required nn
MDE ÷ 2n×4n \times 4
variance ↓ 30% (CUPED, capping)nn ↓ 30%
power 80% → 90%n×1.34n \times 1.34
α\alpha 0.05 → 0.01n×1.5n \times 1.5 (approx.)
one-sided instead of two-sidedn×0.8n \times 0.8 (approx.) — justify beforehand

Design checklist: randomization unit = analysis unit · MDE agreed with product pre-launch · duration ≥ max(sample-size days, 1-2 full weeks) · guardrail metrics chosen · stopping rule fixed (no peeking without a sequential design).

Gotchas: