Build1 publisher3 min readPublished
Repeated A/A tests turned up a 30% false-positive rate on one experimentation platform
The miscalibration sat in the stats engine, against a nominal 5%, beyond the reach of correct math downstream. Routing unallocated traffic into a standing A/A test is how a team measures its own rate.
The Engineer · Build desk

What happened
- A dev.to post on experiment validity prescribes the A/A test: run two completely identical experiences against each other, and treat any difference the pipeline reports as a fault in the testing setup.
- The industry convention flags sample ratio mismatch at p < 0.001, deliberately tighter than 0.05, because at real traffic volumes even a trivial imbalance clears the usual bar.
- In the post's worked example, 100,000 visitors splitting 52,000 to 48,000 instead of 50/50 yields a chi-squared of 160 and a p-value around 10 to the minus 36.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint A significant SRM fixes the reading order: until the split is repaired, no metric from that test can be interpreted, however clean its p-value looks.
- cost The continuous version spends unallocated traffic on a comparison between two identical experiences, and it needs an allocation layer willing to hold a permanent null test.
- exposure Where an engine is miscalibrated, every decision already shipped from it rests on an unknown error rate, and finding the fault takes more than a re-read of the archived p-values.
- decision A segment-level reversal inside a randomized test points the investigation at assignment, not at the segments.
Start with the chi-squared, since it checks by hand. An intended 50/50 on 100,000 visitors puts 50,000 in each arm. The observed 52,000 against 48,000 misses that by 2,000 on each side. Square 2,000, divide by 50,000, and each cell contributes 80; two cells give 160 [9][18]. The post puts the matching p at about 10 to the minus 36 [9].
Teams flag sample ratio mismatch at p < 0.001 instead of 0.05 for exactly this reason [8]. At production volume a trivial imbalance clears 0.05 without effort, and the tighter bar trades a few false alarms for not missing a broken splitter [8].
What breaks a split sits upstream of the statistics: bot traffic skewed into one arm, an ID collision, a redirect that drops users out of their assigned bucket before they are logged [10]. The metric computation runs the same way through all of them. So the p-value comes out correct on a comparison the split has already corrupted [12].
The A/A test aims at exactly this class of fault. According to the post, Microsoft's experimentation team documented a platform where repeated A/A runs turned up a false-positive rate as high as 30% against a nominal 5%, with the stats engine itself miscalibrated [3]. That is six times the design rate, about 30 of every 100 null comparisons flagging a difference where 5 was intended [17][20]. The arithmetic downstream of a miscalibrated engine can be entirely correct [4]. The post does not name the platform or cite the write-up [21].
So the 30% is a measurement of someone else's engine. For the number to transfer, your platform would need the same class of miscalibration, and the way to learn your own figure is to run two identical arms against each other on your own pipeline [1]. If it reports a winner, the fault is in the testing setup [2].
The continuous version is a platform change. Traffic that is not allocated to a real test goes into a permanent A/A, so a regression in the pipeline surfaces before it corrupts an experiment someone is reading [5]. The post calls A/A the cheapest validity check available, underused because it feels like it cannot fail [16]. Routing the spare traffic needs an allocation layer willing to assign users to a null test, plus something watching the output.
Simpson's paradox is the case where the aggregate and the segment numbers are both correct and tell opposite stories [22]. In the 1986 kidney stone study of 700 patients, Treatment B beat Treatment A overall at 83% against 78%, and A won in both the small-stone and the large-stone group [13]. Doctors had given the gentler Treatment B to patients with smaller stones, who were easier cases whatever the treatment [14]. Nobody split anything wrong there; assignment was clinical judgement [15]. In a randomized test the same reversal means something correlated with the outcome landed unevenly across the arms, and the post treats that as the stronger signal of the two [15]. The five-point aggregate gap and both subgroup wins are arithmetically correct [19].
What to watch
- Whether anyone publishes a write-up naming the platform behind the 30% figure, and whether it puts the miscalibration in the variance estimate or the assignment.
- The first A/A rate a team measures on its own pipeline decides whether the 30% figure has anything to do with them.
- Whether experimentation vendors expose a standing null test and its measured false-positive rate as a supported feature.