After studying this material, you should be able to:
Before anything else, you need to understand what makes this environment special.
A standard app has one side:
Company → Users
A retail media marketplace has two sides:
Advertisers (pay money) → Platform → Customers (see ads)
Key constraint: Advertisers have finite budgets. This finite resource is what creates all the problems we will discuss.
Think of it like this: Imagine two restaurants sharing one kitchen. If Restaurant A uses all the stove burners, Restaurant B cannot cook. They are not independent.
Every standard A/B test relies on SUTVA — Stable Unit Treatment Value Assumption.
SUTVA has one critical requirement:
What happens to User A must NOT affect what happens to User B
In a normal app, this holds reasonably well:
Now introduce a shared budget and watch independence collapse:
Scenario:
- Variant A = New, more efficient bidding algorithm
- Variant B = Old baseline algorithm
- Both draw from the SAME campaign budget pool
The chain reaction:
Variant A wins more auctions
↓
Budget depletes faster
↓
Variant B has less money to spend
↓
Variant B performs worse artificially
↓
You conclude Variant A is better...
↓
...but was it really better, or did it just starve Variant B?
This is called Cannibalization Bias — one variant actively degrades the other's performance through shared resource consumption.
Analogy: You test two athletes on a treadmill, but they share one oxygen tank. The stronger athlete breathes more, leaving the weaker one gasping. You cannot fairly compare their natural abilities.
Instead of one shared budget pool, create separate, isolated budget pools per variant.
BEFORE Budget Split:
Campaign Budget ($1000)
├── Variant A draws from here
└── Variant B draws from here (competing!)
AFTER Budget Split:
Campaign Budget ($1000)
├── Sub-budget A ($500) → Only Variant A draws from this
└── Sub-budget B ($500) → Only Variant B draws from this
Step 1: Traffic Randomization
Step 2: Budget Partitioning
Step 3: Isolated Auctioning
Treatment user visits site
↓
Only Treatment sub-campaign budget participates in auction
Control user visits site
↓
Only Control sub-campaign budget participates in auction
By isolating budgets, you create two independent mini-marketplaces:
Universe A (Treatment): Universe B (Control):
- Treatment users - Control users
- Treatment budget - Control budget
- Treatment algorithm - Control algorithm
↑ ↑
No interference between these two universes
Now if Treatment outperforms Control, you can confidently attribute it to the feature, not to budget cannibalization.
Budget Split solves one experiment. But what happens when you want to run two experiments simultaneously?
Experiment 1: Testing new bidding algorithm (variants: 1A, 1B)
Experiment 2: Testing new ad format (variants: 2A, 2B)
Running at the same time = budgets interfere across experiments
Orthogonal means the experiments are mathematically independent — knowing a user's assignment in Experiment 1 tells you nothing about their assignment in Experiment 2.
For two concurrent experiments, each campaign budget is split into four buckets:
Experiment 1 → 1A 1A 1B 1B
Experiment 2 → 2A 2B 2A 2B
------ ------ ------ ------
Budget Bucket: 1A2A 1A2B 1B2A 1B2B
Visual representation:
Experiment 2
2A 2B
┌──────┬──────┐
Experiment 1A│ 1A2A │ 1A2B │
1 ├──────┼──────┤
1B│ 1B2A │ 1B2B │
└──────┴──────┘
Each cell is an isolated budget bucket. Users land in exactly one cell.
When you analyze Experiment 1:
The experiments are orthogonal — they do not distort each other.
Even with Budget Split and Orthogonal Concurrency, perfect isolation is impossible. Here are the remaining interference sources you must understand:
Automated systems adjust bids/budgets based on COMBINED performance
↓
Treatment's performance affects Control's budget allocation
↓
Indirect interference remains
ML models (pCTR, pCVR) train on historical data
↓
Historical data reflects pre-experiment distributions (mostly Control)
↓
Treatment group's model is trained on Control-influenced data
↓
Treatment starts with a biased model
Timeline of contamination:
Past 7-28 days Experiment starts
[Control data] ────────→ [Treatment uses contaminated model]
Ad operations staff manually adjust budgets based on aggregate metrics
↓
They cannot see the experiment split
↓
Their adjustments introduce uncontrolled interference
Campaign runs beyond experiment window
↓
Revenue from those campaigns is cut off mid-measurement
↓
Revenue metrics are artificially depressed or skewed
When isolation cannot be guaranteed, the team pivots to:
Understanding the business value completes the picture:
| Metric | Before (2023) | After (2025) |
|---|---|---|
| Experiments per year | ~8 | 60+ |
| Experiment reliability | Low (flaky) | High |
| Concurrency | Sequential only | Multiple simultaneous |
Reliable experiments
↓
Trustworthy results
↓
Faster decisions (fail fast on bad ideas)
↓
More innovation cycles per year
↓
Competitive advantage
PROBLEM:
Two-sided marketplace → shared budgets → SUTVA violation → Cannibalization Bias
SOLUTION LAYER 1 — Budget Split:
Split campaign budgets proportionally → isolated sub-campaigns per variant
→ Eliminates direct budget cannibalization
SOLUTION LAYER 2 — Orthogonal Concurrency:
Split into N×M budget buckets for N concurrent experiments
→ Experiments cannot interfere with each other
REMAINING CHALLENGES:
- Algorithmic steering
- ML training contamination
- Human interventions
- Right-censoring
FALLBACK:
Causal inference when isolation fails
Answer to Q4: 2³ = 8 buckets (1A2A3A, 1A2A3B, 1A2B3A, 1A2B3B, 1B2A3A, 1B2A3B, 1B2B3A, 1B2B3B)