Meta Pixel event deduplication: why every event needs an event ID
Meta recommends sending your key events twice: once from the visitor’s browser through the Meta Pixel, and once from your server through the Conversions API (CAPI). Each path catches events the other misses. But one purchase sent twice is still one purchase, and Meta needs a way to know that. That process is event deduplication, and the event ID is what makes it reliable.
What Meta event deduplication is and why it matters
Meta’s help article on deduplication describes it as making sure the same event, sent from both the pixel and the Conversions API, is counted only once in your reporting. It names three things that depend on it: conversion rate, return on ad spend and attribution. Without it, Meta warns, you may see artificially high conversion numbers that mislead optimization and budget decisions.
You need deduplication whenever the same event reaches Meta from both sources. That is exactly what Meta’s Conversions API best practices recommend: a redundant event setup, where your key events, for example purchases and checkouts, go through both the pixel and the Conversions API, so the server copy can fill in when the browser copy is lost.
How Meta deduplicates Pixel and Conversions API events
For an event that arrives from both the browser and the server, Meta compares two fields:
- the event name:
Purchasein the pixel call,event_namein the server event; - the event ID:
eventIDin the pixel call,event_idin the server event.
If both match and the second copy arrives within 48 hours of the first, Meta keeps one and discards the other. According to its developer documentation, it generally prefers the copy it received first.
The same logic works within one source. Meta’s help article says deduplication also applies to repeated pixel events with an identical name and event ID, and to repeated server events with an identical event_name and event_id.
There is a fallback: matching on the event name plus fbp (the pixel’s browser ID cookie) or external_id (your own customer ID). Meta lists two limits for it: it generally only works when the browser event arrives before the server event, and it does not deduplicate events that come from a single source. Treat it as a safety net, not a plan.
What happens to reporting when deduplication fails
Deduplication can fail in both directions, and each one distorts your numbers differently.
Double counting. With no IDs, or different IDs on each side, Meta cannot reliably tell the two copies apart, so the same purchase may count twice. Results look better than reality, cost per purchase looks lower than it is, and the delivery system optimizes on inflated numbers. One sign to watch for: conversions jump when the Conversions API is switched on, while orders stay flat.
Dropped events. The opposite mistake. If the same ID is reused, for example a hard-coded "purchase" or a variable that never changes, Meta sees a stream of events with identical names and IDs and treats every one that follows within 48 hours as a duplicate of the first. Real conversions disappear.
IDs generated twice. The browser creates its own random ID and the server creates another. Both events have an ID, the IDs never match, and the effect is the same as having none.
Different names. The IDs match, but the pixel sends Purchase and the server sends a custom order_completed. Different names, no deduplication. Meta’s troubleshooting advice is to confirm that event_name and event_id are formatted identically across sources.
Late server copies. Meta accepts website events up to 7 days after they happened, but only deduplicates within 48 hours. A server job that sends orders in a batch three days later lands outside that window, so those purchases can count again.
Choosing the event ID and keeping it identical
Meta’s server event reference says the ID can be any unique string you choose. For purchases, it suggests the order number or transaction ID: two orders, 123 and 456, each sent from browser and server with their own number, are understood as two purchases rather than four. For events without a natural ID, a random value works, as long as both sides send the same one.
Four rules cover most setups:
- One ID per action. Per purchase, per lead, per page view. Never per session or per visitor.
- The exact same string on both sides. A prefix such as
order-10482is fine if both sides use it. - Create it once, in one place, and hand it to the other side.
- The same event name on both sides. This applies to custom events too: the server’s
event_nameaccepts standard and custom names, and deduplication compares them, so a custom event needs the identical name in the pixel and on the server.
In the pixel, the ID goes in the fourth argument of fbq, which Meta’s pixel reference recommends when you use the pixel alongside the Conversions API. Two patterns cover most custom code.
When the server knows the ID first, as with a purchase, use the order number. Send it as event_id in your Conversions API call and print it into the thank-you page’s pixel call:
fbq('track', 'Purchase', { value: 49.90, currency: 'EUR' }, { eventID: 'order-10482' });
When the browser acts first, as with a lead form, create the ID in the browser, give it to the pixel, and send it to your server with the form so the server can reuse it:
const eventId = crypto.randomUUID();
fbq('track', 'Lead', {}, { eventID: eventId });
form.elements.event_id.value = eventId; // hidden field; the server sends it as event_id
Setting it up on Shopify, WooCommerce and Google Tag Manager
Deduplication works with all the common platforms. Meta’s help article says partner integrations such as Shopify and WooCommerce handle the deduplication parameters automatically. Your part is to make sure nothing else sends the same events.
Shopify, with Meta’s Facebook & Instagram app. The app adds the Conversions API when customer data sharing is set to Enhanced or Maximum. Keep the app’s pixel the only one. A pixel pasted into the theme, added as a custom pixel or sent by a second app produces events without the app’s IDs.
WooCommerce, with Meta for WooCommerce. WooCommerce’s documentation says pixel and Conversions API data are deduplicated on a unique event ID. The same warning applies: check your theme, Google Tag Manager and other plugins for a second pixel.
Meta-enabled Conversions API. In Meta’s comparison of setup options, events shared through the pixel are also shared through this server connection and are deduplicated automatically.
Meta’s Conversions API Gateway. Meta says the Gateway generates the event ID automatically and passes it to both channels.
Google Tag Manager with a server-side container. Meta’s guide for server-side Tag Manager works like this:
-
Create a variable that returns a unique ID per event. Meta’s guide builds one from Tag Manager’s own event data:
function() { var gtmData = window.google_tag_manager[{{Container ID}}].dataLayer.get('gtm'); return gtmData.start + '.' + gtmData.uniqueEventId; } -
Put that variable in the event ID field of your Meta Pixel tag. In a Custom HTML tag it goes in the fourth argument of
fbq, as{ eventID: ... }. -
Send the same variable to the server container as an event parameter,
event_idon the GA4 event tag. Withgtag, Meta’s guide uses a custom parameter:gtag('event', 'purchase', { 'x-fb-event_id': eventId }). -
In the server container, Meta’s Conversions API Tag sends that value as
event_id.
Fire the pixel tag and the GA4 tag on the same trigger, so both read the variable for the same event, and make sure both send the same event name.
Duplicates caused by multiple tags or integrations
Deduplication merges a browser copy and a server copy that share an ID. It cannot clean up copies that should never have been sent. The usual sources:
- Two pixel installations. The base code sits in the theme and in a Tag Manager tag, or a plugin installed its own pixel next to a manual one. Every action then sends two browser events, usually without matching IDs. This is the problem our duplicate Meta Pixel events guide covers, with steps to find and remove the extra copy.
- Two server-side senders. A platform integration and a separately installed Gateway or Conversions API app both send
Purchase. Unless both happen to use the same event ID, Meta has no way to merge them. - Overlapping tags. Two Tag Manager tags send the same event on different triggers, for example one on form submission and one on the thank-you page.
The rule: one pixel installation and one server-side sender per pixel, both using the same ID. If your setup sends the same event twice from the browser, fix that before you tune event IDs.
How to test and monitor deduplication in Events Manager
- Browser side. Open your site in a private window with developer tools on the Network tab, filter by
facebook.com/trand trigger a key event. Each request should carry aneidvalue that changes from one action to the next. Our event ID guide shows what to look for. - Test events. In Events Manager, open your pixel (dataset) and go to Test events. Use Open website for browser events, and add the
test_event_codeshown there to server events from your own code. Remove it afterwards: Meta says these events are not dropped. The test events tool shows which events were processed and which were deduplicated. - Event deduplication tab. On the overview, click View details for an event and open Event deduplication. Its table shows what share of pixel and server events carried each deduplication key, and the overlap: the share received from both sources. Meta recommends sending deduplication keys with all your events; the higher both numbers, the better.
- Do not judge by the total. Meta says the “events received” figure on the Event overview tab is the sum of pixel and server events, not deduplicated, so it will look high even when deduplication works. The same tab should show server events matching or exceeding pixel events.
- Keep watching. The Diagnostics tab lists problems Meta has detected, and Meta suggests looking for unexpected spikes or drops in event counts. Meta Ads Data Advisor (formerly Meta Pixel Helper), Meta’s Chrome extension, helps check what the browser side sends.
These event breakdowns are available for website events sent through the Conversions API, as Meta’s article on server event details explains.
How to diagnose duplicate or mismatched events
Meta lists three common causes: a mismatched or missing event_id, delays between browser and server delivery, and incorrect parameter names or values. Match the symptom to the cause:
- Conversions jumped when the Conversions API went live. The server copies are not being merged. Check that both sides send an ID, that the IDs are the same, and that the names match.
- Conversions dropped after you added event IDs. The ID is probably reused. Trigger two test actions and compare their
eidvalues in the Network tab: they must differ. - The deduplication tab shows few server events with
event_id. Your server code or tool does not send the ID. Check its settings or the payload it sends. - Both sides carry
event_id, but the overlap stays low. The IDs are generated twice, or the names differ. Compare one real action end to end: note theeidin the browser request, find the same action in your server log or tool, and compare both values character by character. - Server events arrive hours or days late. The Data freshness tab shows the delay. Copies that arrive more than 48 hours after the first are not deduplicated.
- The same browser event appears twice in Test events. That is a second pixel installation, not a deduplication problem. See the section on multiple tags above.
Do you need deduplication with only the Pixel or only the Conversions API?
Not across sources. Meta’s help article says deduplication is needed when you send the same event from both, and not needed when each source sends different events, for example AddToCart from the browser and Purchase from the server.
Event IDs are still worth adding:
- Meta also deduplicates repeated events from one source that share a name and event ID. With an order number as the pixel’s event ID, a thank-you page reloaded within 48 hours is treated as a repeat of the same purchase rather than a new one.
- The
fbpandexternal_idfallback never works with a single source, so the event ID is the only key that does. - Meta recommends the redundant setup. The day you add the Conversions API, your browser events need IDs, and it is easier when they already have them.
Check your own setup
If you have not set up server events yet, our Conversions API setup guide compares the options, with and without a developer. The free IsPixelWorking check shows whether your browser events carry event IDs, whether the same event is sent twice, and whether we see signs of server-side tracking.
Check your own pixel. Paste a landing page and see what it sends to Meta before and after consent. Free, about a minute.
Check a page