Written by
Halkwinds Editorial Team
Halkwinds Research & Editorial

A/B Testing Infrastructure: Building Statistical Rigor Into Products
How to build an experimentation platform that gives reliable causal estimates — assignment, tracking, power analysis, and common mistakes.
Every product manager has shipped a feature that "obviously" would move the needle, only to watch the metrics flatline — or worse, quietly decline. The problem is rarely the idea. It's the absence of infrastructure to tell you, with statistical confidence, whether a change actually caused an improvement. A/B testing infrastructure is the difference between running experiments and running guesses with extra steps. This article walks through how to build an experimentation platform that produces reliable causal estimates: how assignment works, what to track, how to size your tests with power analysis, and the mistakes that silently corrupt results.
- Background / Why This Matters
- Core Concepts and Architecture
- Implementation Strategy
- Scaling and Operational Considerations
- Common Mistakes / What to Avoid
- Frequently Asked Questions
- Conclusion
Background / Why This Matters
A/B testing exists to answer one deceptively hard question: did this change cause the outcome we observed, or would it have happened anyway? Correlational analytics — dashboards, funnels, cohort charts — describe what happened. Experimentation is the only tool most product teams have to establish causation without a controlled scientific lab.
The stakes are higher than they look. Research from large-scale experimentation programs at companies like Microsoft and Booking.com has repeatedly suggested that the majority of ideas tested either have no effect or a negative one. Estimates vary by domain, but the recurring theme is humbling: teams are wrong about their own features far more often than intuition allows. Without infrastructure to catch those failures, you ship them.
The pain points product managers feel are usually symptoms of missing infrastructure:
- "We ran the test but I don't trust the result." Usually a sign of inconsistent assignment or biased sampling.
- "The winning variant didn't hold up in production." Often peeking at results early and stopping when significance briefly appears.
- "We can't tell if the test was even big enough." No power analysis, so the experiment never had a chance to detect the effect.
Takeaway: Treat experimentation as infrastructure, not a feature. If assignment, tracking, and statistics aren't systematized, your results are opinions wearing lab coats.
Core Concepts and Architecture
A functioning A/B testing platform has four cooperating subsystems: assignment, exposure logging, metric computation, and statistical analysis. Get any one wrong and the whole chain produces garbage.
1. Assignment (randomization)
Assignment decides which user sees which variant. The gold standard is deterministic hashing: take a stable unit ID (user ID, account ID, or device ID), concatenate it with the experiment key, hash it (e.g., MD5 or MurmurHash), and map the hash to a bucket. This guarantees the same user always gets the same variant without storing state, and it makes assignment reproducible for debugging.
Two decisions matter here. First, choose your unit of randomization deliberately — user, session, or account. If your product is used by teams, randomizing individual users inside the same account causes interference. Second, use a consistent salt per experiment so that a user assigned to treatment in one test isn't correlated with their assignment in another.
2. Exposure logging
You should only analyze users who were actually exposed to the experiment, not everyone who was eligible. Fire an exposure event at the moment the variant-affecting code executes. This prevents dilution — including users who never reached the feature drags your effect size toward zero and destroys statistical power.
3. Metric computation
Define metrics before the test starts. You need a small number of primary metrics (the thing you're trying to move), guardrail metrics (things that must not regress — latency, error rate, churn), and secondary metrics for exploration. Precommitting prevents the temptation to fish for any metric that happens to look good.
4. Statistical analysis
This layer turns raw numbers into a decision. It computes effect sizes, confidence intervals, and p-values (or Bayesian posteriors), applies corrections for multiple comparisons, and handles sequential-testing concerns. Modern platforms increasingly favor sequential testing methods that let you monitor results continuously without inflating false positives — the classic fix for the "peeking" problem.
Build vs. buy
Most teams should not build all four layers from scratch. Here's how the common options compare:
| Tool | Best for | Stats approach | Hosting |
|---|---|---|---|
| Statsig | Product teams wanting fast setup with warehouse-native option | Sequential + regression-adjusted (CUPED) support | Cloud or warehouse-native |
| Optimizely | Marketing/web experimentation, enterprise programs | Sequential (Stats Engine) | Managed cloud |
| GrowthBook | Engineering-led teams wanting open source + data control | Bayesian and frequentist, CUPED | Open source / self-host / cloud |
Takeaway: Buy the SDK and stats engine, own your data. A hybrid where a tool like GrowthBook or Statsig computes results against your data warehouse gives you speed without surrendering metric definitions.
Implementation Strategy
A pragmatic rollout sequence keeps you from over-engineering before you've run a single valid test.
- Instrument a stable identity. Before anything, ensure you have a durable unit ID that survives page reloads and sessions. Broken identity is the number one cause of unreliable experiments.
- Wire up assignment and exposure. Integrate an SDK (Statsig, GrowthBook, or Optimizely). Fire the exposure event at the decision point, not at page load.
- Define your metric layer. Connect the platform to your warehouse (Snowflake, BigQuery, or Redshift). Write metric definitions as versioned SQL so they're auditable and reusable across experiments.
- Run an A/A test. Split traffic between two identical experiences. If your platform reports a "significant" difference, your pipeline is broken — a false positive rate around 5% is expected, anything wildly higher signals a bug.
- Do power analysis before every real test. Decide the minimum detectable effect (MDE) you care about, plug in baseline conversion rate and variance, and compute the sample size and runtime needed. A test that can't reach adequate power is not worth running.
Power analysis in plain terms
Power is the probability your test detects a real effect if one exists. Underpowered tests are worse than no test — they produce noisy results that occasionally look significant by chance. The three levers are baseline rate, MDE, and sample size. If you can only realistically get 20,000 users into an experiment and detecting a 1% relative lift requires 400,000, either widen your MDE, run longer, or don't run the test.
A common rule of thumb from experimentation practitioners: if you have to squint at the runtime to justify the experiment, you're going to squint at the results too.
This is where a specialized partner helps. Halkwinds' Data & Analytics practice frequently sets up warehouse-native experimentation for teams that have plenty of product data but no reliable pipeline connecting it to statistical decisions — closing the gap between "we have dashboards" and "we can prove causation."
Takeaway: Ship the A/A test and a power calculator before you ship your first real experiment. They're the guardrails that make everything downstream trustworthy.
Scaling and Operational Considerations
An experimentation platform that works for one test per month breaks in surprising ways at fifty tests per month. Plan for scale early.
Variance reduction
As you run more tests, reducing variance means faster, cheaper experiments. CUPED (Controlled-experiment Using Pre-Experiment Data) uses each user's pre-experiment behavior to shrink noise — practitioners report meaningful reductions in required sample size in many cases. Statsig, GrowthBook, and Optimizely all offer some form of it. Turn it on.
Interaction and interference
When many experiments run simultaneously, they can interact. Most of the time random assignment keeps them orthogonal, but overlapping experiments touching the same UI can conflict. Use mutually exclusive layers (holdout groups that never share traffic) for tests that genuinely interfere, and let the rest overlap.
Governance and review
- Experiment registry: every test has an owner, hypothesis, primary metric, MDE, and end date recorded before launch.
- Guardrail alerts: automatically stop a test if a guardrail metric (errors, latency, revenue) breaches a threshold.
- Peer review: a lightweight review of the design before launch catches most sizing and metric-definition errors.
Long-term holdouts
Short tests measure short-term effects. To catch novelty effects and long-term degradation, keep a small percentage of users in a persistent holdout that never receives new features for a quarter. It's the only honest way to measure your cumulative product impact.
Takeaway: Invest in variance reduction and governance once you cross roughly ten concurrent experiments. Below that, keep it simple; above it, discipline pays for itself.
Common Mistakes / What to Avoid
Most invalid experiments fail for a handful of recurring reasons.
- Peeking and early stopping. Checking results daily and stopping when p < 0.05 first appears inflates false positives dramatically. Fix: use a sequential-testing engine, or commit to a fixed sample size and don't look until it's reached.
- Sample ratio mismatch (SRM). If you expected a 50/50 split but observe 52/48 with large N, something in assignment or logging is broken. Always run an SRM check; a failing check invalidates the whole test.
- Dilution from eligibility, not exposure. Analyzing everyone eligible instead of everyone exposed washes out your effect. Log exposure at the decision point.
- Metric fishing. Testing twenty metrics and celebrating
Explore Further