1. Definitions
Let’s define the numbers you already have:
| Variable | Meaning |
|---|---|
CF_uv | Cloudflare unique visitors (all IPs, bots + humans) |
CF_req | Cloudflare total requests |
Mat_uv | Matomo unique visitors (JS-enabled humans) |
Mat_pv | Matomo pageviews |
bot_factor | Estimated % of Cloudflare traffic that is bots (0–1) |
JS_factor | Fraction of real humans that trigger Matomo/JS (0–1) |
2. Step 1: Estimate human visitors from Cloudflare
HumansCF=CF_uv×(1−bot_factor)
- Example:
bot_factor = 0.98(98% bots)
HumansCF=2,580,000×(1−0.98)=51,600
3. Step 2: Adjust Matomo for JS undercounting
Humansreal=Mat_uv/JS_factor
- Example:
JS_factor = 0.05(only 5% of humans trigger JS)
Humansreal=2,509/0.05≈50,180
✅ Notice this roughly matches the Cloudflare-estimated human count.
4. Step 3: Estimate real ad impressions
If your ad triggers on each pageview:
AdImpressionsreal=Humansreal×AvgPagesPerHuman×AdEngagementFactor
AvgPagesPerHuman≈ Mat_pv / Mat_uv = 5,769 / 2,509 ≈ 2.3AdEngagementFactor= fraction of pages where ad is actually viewed (0–1), e.g., 0.5
AdImpressionsreal=50,180×2.3×0.5≈57,700
- Compare to Cloudflare requests (8.3M) — huge difference because most requests are bots or non-engaged humans.
5. Step 4: Optional shortcut formula
AdImpressionsreal≈Mat_uv×JS_factor1×Mat_uvMat_pv×AdEngagementFactor
- Only requires Matomo numbers + your estimate of JS coverage + ad view factor.
- No need to deal directly with raw Cloudflare numbers unless you want bot analysis.