Blog

The right way to dedupe across multiple destinations

One event_id, applied consistently across every destination, scales to as many platforms as you add.

Once you are forwarding events to GA4, Meta, TikTok, LinkedIn, and your warehouse, the deduplication strategy needs to scale. The pattern that works: generate a single event_id at the source, propagate it identically to every destination, and let each destination handle its own dedup logic.

Generate the ID once

On the page, when the event fires, generate a UUID and push it into the data layer:

const eventId = crypto.randomUUID();
dataLayer.push({
  event: 'purchase',
  event_id: eventId,
  ecommerce: { transaction_id: 'T-12345', value: 99.00, currency: 'EUR' }
});

Use the same event_id for both client-side and server-side firings of the same event.

Forward identically to each destination

In your sGTM container, every tag that fires on the purchase event reads the event_id and includes it in the outgoing payload, mapped to whatever the destination calls it.

DestinationField name
GA4No dedup at event level. Use transaction_id for ecommerce dedup.
Meta CAPIevent_id
TikTokevent_id
LinkedInconversionId (combined with conversionRuleId for matching)
Snapchatclient_dedup_id
Redditclick_id (yes, called click_id even for dedup)

GA4 is the exception

GA4 does not deduplicate at the event_id level. Two purchase events with the same transaction_id are deduplicated automatically; for other event types you have to ensure they only fire once. The double-counting troubleshooter covers this.

Verify each destination separately

In Meta Events Manager, the dedup column tells you how many events were received from both Pixel and CAPI. Above 80 percent overlap means dedup is working. Below means the event_id is not propagating correctly to one side.

In TikTok Events Manager, the equivalent is the "Browser + Server" indicator. In LinkedIn, you have to check your conversion volume; if it doubles when you turn on CAPI, dedup is failing.

When the same event_id needs to span sessions

For events that fire across sessions (a checkout that starts in one session and completes hours later in another), the event_id needs to be persisted across the gap. Store it in a cookie or localStorage tied to the cart or session, and read from there at conversion time. Without this, your dedup will silently fail for cross-session conversions.