demo · v134

Reach Measurement: Before vs After v134

Before Chrome 134, reach was estimated by calling sharedStorage.append() on every ad impression — each worklet run could only observe whether it ran, not which campaigns the user belongs to. Cross-campaign deduplication required workarounds like per-campaign keys and approximate frequency counters. v134 adds interestGroups() to the worklet, letting a single run read all audience memberships and emit an exact, deduplicated reach count.

Campaign A only
Campaign B only
Both (A + B)
Neither
Before v134 — append() approximation

User population (24 users)

Worklet runs (per impression)

Each campaign fires a separate worklet. append() adds a token per run — can't cross-reference campaigns. Result: users in both are counted twice.

Campaign A count
Campaign B count
Combined reach
// Per-campaign worklet (pre-v134) // Called once per impression — no IG access sharedStorage.worklet.run('countReach', { data: { campaign: 'A', token: sessionToken } }); // Key: cannot see Campaign B membership from here. // Separate worklet runs accumulate tokens independently.
After v134 — interestGroups() deduplication

User population (same 24 users)

Single worklet run (cross-campaign)

A single worklet reads interestGroups() and sees all campaign memberships. Users in both campaigns counted exactly once.

Campaign A reach
Campaign B reach
Combined reach (deduplicated)
// Cross-campaign worklet (v134+) const igs = await sharedStorage.interestGroups(); const inA = igs.some(g => g.name === 'campaign-a'); const inB = igs.some(g => g.name === 'campaign-b'); // Emit a single aggregate contribution if (inA || inB) { privateAggregation.contributeToHistogram({ bucket: BigInt(REACH_BUCKET), value: 1 // each user counted once }); }
// The key difference:
//
// Pre-v134: two separate worklet calls accumulate independently
//   run('reach-a') → sees token for A, no knowledge of B
//   run('reach-b') → sees token for B, no knowledge of A
//   combined = countA + countB  ← users in BOTH counted twice
//
// v134+: one worklet, reads interestGroups()
//   const igs = await sharedStorage.interestGroups();
//   const inAny = igs.some(g => ['campaign-a','campaign-b'].includes(g.name));
//   if (inAny) contribute(1);  ← users in BOTH counted exactly once
//
// The noise reduction scales with campaign overlap:
// if 20% of users are in both campaigns, pre-v134 over-reports combined reach by ~20%.

see also