A/B Testing Platform — Optimizely/GrowthBook-class experimentation system: Client SDK with in-process bucketing, Control Plane with config CDN and SSE kill-switch, Event Ingest via Kafka+Flink, Stats engine with mSPRT sequential testing, Druid for real-time agg, Guardrail auto-stop. 5 scenarios + 2 ADRs.
This is a reference design for randomized product experiments, not a claim about one vendor's private implementation. It separates four things that are often incorrectly collapsed: deterministic assignment, actual treatment exposure, outcome attribution, and statistical inference. Correctness depends on a declared randomization unit, immutable experiment versions, replayable event data, and an analysis policy fixed before results are inspected.
| Node | Responsibility |
|---|---|
| Product App / Experiment SDK | Evaluate a signed config and activate a variant. High-risk permissions are still enforced server-side. |
| Signed Config CDN / Experiment API / Registry | Publish immutable allocations and a short-TTL emergency denylist; preserve configuration history. |
| Collector / Event Log | Validate events, attach ingestion metadata, retain a replayable ordered stream. |
| Event-Time Processor | Re-key, deduplicate, join within declared windows, and route invalid or late records explicitly. |
| Deduplicated Facts | Analysis-ready exposure and outcome facts; never the only copy of raw input. |
| Statistics Worker / Results Store | Reproducible estimators, sample-ratio checks, multiplicity policy, and audited results. |
| Guardrail Monitor | Applies a preregistered sequential rule with persistence/hysteresis; it does not repeatedly peek with an ordinary fixed-horizon p-value. |
The config is signed and cached. The SDK hashes a canonical tuple and maps it to a versioned bucket interval. A rollout operation must specify whether existing assignments are preserved. Assignment is stable only within the documented experiment version and identity policy; anonymous-to-authenticated identity transitions need an explicit rule.
The exposure record means treatment activation, not a configuration lookup. Outcomes and exposures meet on the same experiment/unit key or on a durable assignment id. A first-qualifying-exposure policy avoids quietly changing cohorts when an SDK emits several exposures. Event-time intervals prevent an outcome from being joined merely because it arrived near an exposure in processing time.
The displayed numbers are an illustrative, internally coherent load and power example, not production telemetry.
For a two-sided test of proportions, a rough planning approximation is:
n per arm ≈ 2 × p × (1 − p) × (z(alpha/2) + z(power))² / delta².
With baseline p = 0.10, minimum detectable difference delta = 0.0015 (0.15 percentage points), alpha = 0.05, and 80% power, this gives about 628,000 units per arm before attrition or clustering adjustments.
The animation freezes 700,000 units per arm with control 10.00% and treatment 10.18%. The unpooled standard error is:
sqrt(0.1000 × 0.9000 / 700000 + 0.1018 × 0.8982 / 700000) = 0.000509,
or 0.0509 percentage points. The 0.18 percentage-point effect therefore has z ≈ 3.54, two-sided p ≈ 0.0004, and an ordinary fixed-snapshot 95% interval of approximately [0.080, 0.280] percentage points. This ordinary interval is not automatically valid after optional stopping. Continuous decisions need an always-valid or otherwise sequentially calibrated design.
CUPED-style variance reduction is dataset-dependent. In the idealized single-covariate case its variance factor is related to (1 − rho²); there is no universal 30–50% gain.
Sample-ratio mismatch compares observed assignment counts with the configured allocation. An exact 25/25/25/25 split has chi-square zero and p = 1, so the diagram instead uses an explicitly illustrative chi-square of 3.2 with 3 degrees of freedom (p about 0.36).
The multiple-testing family must be declared. Four arms create six all-pairs contrasts, but only three treatment-versus-control contrasts. Bonferroni/Holm control family-wise error; Benjamini–Hochberg targets false discovery rate. They are different guarantees, not interchangeable decorations.
A stop is triggered only by the preregistered safety rule and a sustained window, then audited. The control plane stops new assignment and publishes a signed denylist. Connected server SDKs or polling clients converge within their configured refresh behavior; an offline device cannot be promised a five-second push. Safety-critical access therefore remains server-authoritative.
No request volume is presented as an industry fact. For a deployment-specific worksheet:
Measure skew by experiment and randomization unit. A single global launch can dominate a partition even when average throughput is comfortable.
It does not claim that a particular hash family is always unbiased, that ordinary p-values survive repeated peeking, that CUPED has a fixed improvement, or that a kill switch reaches disconnected clients instantly. It also does not turn an observational dashboard slice into a randomized conclusion.
Введите числа или выберите пресет