What you'll learn
- How CUPED reduces variance in A/B tests using pre-experiment data
- How sequential testing lets you peek early without inflating false-positive risk
- How to implement both techniques with simple code and visual checks
- When to combine these methods for maximum efficiency
Why Variance Reduction Matters
High metric noise leads to slow experiments. A subtle 2% improvement in revenue can be drowned out by day-to-day randomness. The solution? CUPED (Controlled-experiment Using Pre-Experiment Data) uses correlated pre-period metrics to reduce post-period variance.
If baseline and experiment periods are correlated, we can subtract the predictable component:
CUPED formula:
Y_cuped = Y - θ(X - X̄)
Where:
Y= observed experiment metricX= pre-experiment baseline metricθ = Cov(X,Y) / Var(X)= adjustment coefficientX̄= mean of baseline
The more correlated X and Y are, the greater the variance reduction.
Interactive CUPED Demo
Adjust the correlation slider below to see how CUPED variance reduction works. Higher correlation between baseline and experiment metrics leads to greater variance reduction.
Observations:
- Low correlation (ρ ≈ 0.2): minimal improvement
- High correlation (ρ ≈ 0.8): 64% variance reduction
- Variance reduction ≈ ρ² (correlation squared)
Sequential Testing
Instead of fixing a sample size upfront, sequential testing analyzes cumulative data over time while controlling error rates. This allows early stopping when evidence is overwhelming.
Key points:
- Orange line tracks p-value as samples accumulate
- Dashed lines represent significance thresholds (α = 0.05 and α = 0.01)
- When p-value crosses threshold, you can stop early with controlled Type I error
- Sequential testing typically saves 30-40% of samples compared to fixed-horizon tests
Implementation Code
Here's how to generate CUPED demo data and implement the variance reduction:
import numpy as np
import pandas as pd
# Load experiment data
df = pd.read_csv("cuped_demo.csv")
# Calculate adjustment coefficient θ
theta = np.cov(df["pre_metric"], df["post_metric"])[0,1] / np.var(df["pre_metric"])
# Apply CUPED adjustment
df["y_cuped"] = df["post_metric"] - theta * (df["pre_metric"] - df["pre_metric"].mean())
# Calculate variance reduction
reduction = 1 - df["y_cuped"].var() / df["post_metric"].var()
print(f"Variance reduction: {reduction:.2%}")Interpreting Results
| Technique | Goal | Interpretation |
|---|---|---|
| CUPED | Reduce variance using pre-period covariate | Narrower CI → faster detection |
| Sequential | Check significance progressively | Detect early winners without bias |
| Combined | CUPED + Sequential | Maximum sensitivity at minimal data cost |
Real-World Applications
| Company | Technique | Outcome |
|---|---|---|
| Airbnb | CUPED on booking conversion + pre-trip features | Reduced required sample size by ≈40% |
| Netflix | Sequential testing (O'Brien-Fleming boundaries) | Ends 10% of experiments early with controlled α |
| Uber | CUPED + guardrails | Keeps experimentation latency low for re-ranking models |
Key Takeaways
Precision Experimentation Checklist
- CUPED leverages pre-period metrics to reduce noise
- Variance reduction ≈ faster decisions, smaller samples
- Sequential testing controls Type I error while allowing early stopping
- Combined methods enable continuous experimentation in production MLOps systems