About 8 percent of sessions never send events, traced it to ad blockers
As the growth lead I reconciled our Croct session counts against raw server logs and found a consistent gap: roughly 8.2% of sessions in the logs never appear in Croct, and the gap jumps to about 19% on Firefox specifically.
Dug into it with a blocker-enabled browser and the pattern is clear: requests to the evaluate and track endpoints get blocked by EasyPrivacy-listed rules, so those sessions send nothing.
Before I write this off as measurement noise, how are other teams handling it? Losing a fifth of Firefox traffic from every experiment sample worries me.
2 answers
You diagnosed it correctly. EasyList/EasyPrivacy block the /client/web/evaluate, /client/web/track, and /content endpoints in any browser with those lists enabled, so client-side calls from affected sessions never arrive.
The remedy is first-party proxying. Point the SDK at your own domain and forward to Croct server-side, so the browser only ever makes same-origin requests that blockers have no reason to touch:
croct.plug({ appId: 'YOUR_APP_ID', baseEndpointUrl: 'https://yourdomain.com/api/croct', cidAssignerEndpointUrl: 'https://yourdomain.com/api/croct/cid',});Behind those paths you run a thin reverse proxy to the Croct endpoints. We did this after finding a similar gap and the blocked share dropped to effectively zero.
If any of your content is resolved server-side with fetchContent, that part is already unaffected. The server talks to Croct directly and the browser never makes the call, so blockers cannot interfere with what gets rendered. Ad blockers are a known blind spot for client-side testing tools generally, they silently exclude a chunk of traffic and skew samples exactly the way you noticed.
So the practical split is: server-side resolution for content and variant assignment (immune by design), first-party proxy per Petra's answer for the client-side event tracking. Between the two your Firefox gap should close almost entirely.