Meta Pixel Firing Twice? How to Find and Remove Duplicate Events

Quick fix: Duplicate events almost always mean the pixel is installed twice, for example once in the theme and once through an app or Google Tag Manager. Search the page source and your GTM container for fbq('init', keep exactly one installation, and remove the rest.
When the same PageView or Purchase shows up twice for a single action, your reports inflate, your cost per result looks better than it is, and campaign optimization learns from bad data. The good news is that duplicates are usually easy to trace once you know where to look.
This guide covers the causes in order of how often they appear, how to confirm each one in the browser, and how to clean them up without breaking tracking you actually need.
First, confirm it's really a duplicate
Open DevTools, go to the Network tab, enable "Preserve log", and filter by facebook.com/tr. Reload the page once. Each request is one event sent to Meta. For each request, note two query parameters:
id=is the pixel ID that received the event.ev=is the event name, such asPageVieworPurchase.
Now compare:
- Same
id, sameev, two requests: a true duplicate. The pixel is counting one action twice. - Different
id, sameev: two pixels each received one event. That may be intended (for example, an agency pixel and your own), but each pixel only counts it once. - Browser event plus a server event: if you use the Conversions API, Events Manager shows both. That is not a duplicate if deduplication is configured. See our guide to Pixel and Conversions API deduplication.
A pixel inspector such as the Pixel Helper extension can show the same thing at a glance, including how many times each event fired on the page.
1. The pixel is installed by both the theme and an app
This is the most common cause on hosted store platforms. Someone pasted the base code into the theme years ago, and later the store connected a platform integration that also installs the pixel. Both run on every page, so every PageView is sent twice.
On Shopify, for example, the Facebook & Instagram channel manages the pixel connection under its data sharing settings. Shopify's help center notes that a pixel hand-coded into your theme alongside the integration can cause duplicate or incorrect data. See Shopify's data sharing settings guide and our article on Shopify pixels and customer events.
How to confirm: view the page source and search for fbevents.js. A copy inside your theme's header markup alongside a second one loaded by an app or sandbox is the signature.
Fix: choose one owner for the pixel. If a platform integration is available, it is usually the better choice because it also handles checkout pages and server events. Remove the hand-coded snippet from the theme files, including any old event snippets on the order confirmation page.
2. Google Tag Manager also loads the pixel
The second most common pattern is a GTM Custom HTML tag with the full base code, while the same code also sits in the site template or arrives through a plugin. GTM duplicates are easy to miss because the code isn't visible in the page source.
How to confirm: open your GTM container and search tags for fbq or fbevents. In Preview mode, check which tags fire on page load. If a Meta tag fires and the page source also contains base code, you have two installations.
Fix: keep the pixel in one place. If GTM is your standard, remove the hard-coded copy; if not, pause the GTM tag. Watch for several GTM tags that each contain the entire base code (one per event) instead of one base tag plus small event tags. Our guide on duplicate tags from gtag and GTM covers the same pattern for Google tags.
3. Event code runs twice on the same page
Purchase duplicates often come from the thank-you page rather than the base code. Typical sources:
- An integration sends Purchase and a manually added snippet on the confirmation page sends it again.
- The confirmation page fires Purchase on every load, so a refresh or a revisit from an order email counts again.
- A GTM trigger such as "Page View" and a custom dataLayer event both match, firing the same tag twice.
Fix: remove the extra snippet, and make sure the event fires once per order. A common approach is to fire Purchase only when the order is first viewed, using a flag your backend sets or an order-scoped value in storage. If you also send Purchase through the Conversions API, pass the order ID as the event ID in both places so Meta can deduplicate.
4. fbq('init') is called twice for the same ID
Two copies of the base code mean two init calls and two automatic fbq('track', 'PageView') calls. Sometimes only the init is duplicated, for example when a developer re-initializes the pixel to add advanced matching data later in the page.
How to confirm: search the rendered DOM in the Elements tab (not just the source) for fbq('init'. Count matches and note which script each comes from.
Fix: call init once per pixel ID, as early as possible, and call fbq('track', 'PageView') once. If you need to pass customer data for advanced matching, include it in that single init call rather than initializing again.
5. Multiple pixel IDs share plain track calls
Many sites legitimately run more than one pixel. The catch is that a plain fbq('track', 'Purchase', ...) sends the event to every pixel that has been initialized on the page. If each installation also fires its own Purchase, every pixel receives the event several times.
Meta's advanced pixel documentation warns that plain track calls on pages with multiple initialized pixels can produce over-firing or unexpected behavior. It recommends trackSingle and trackSingleCustom to target one pixel:
fbq('init', '111111111111111');
fbq('init', '222222222222222');
// Sent only to the first pixel
fbq('trackSingle', '111111111111111', 'Purchase', {
value: 59.90,
currency: 'USD'
});
// Custom event sent only to the second pixel
fbq('trackSingleCustom', '222222222222222', 'PartnerSale', {
value: 59.90,
currency: 'USD'
});
Fix: list every pixel ID that loads on your site and decide which events each should receive. Remove pixels nobody owns anymore. For the rest, switch event calls to trackSingle where pixels need different events.
6. A single-page app double-fires PageView
In single-page apps, a developer may add fbq('track', 'PageView') to the router on top of the PageView in the base code, so the first page records two. Or a component that contains the base code mounts again on each route.
Fix: load the base code once in the app shell, and fire route PageViews only on actual navigations, not on the initial render. Then click through several routes and count the PageView requests: you want exactly one per navigation.
Removing the duplicate safely
- Inventory first. Write down every place pixel code lives: theme files, platform integrations, apps, GTM tags, plugins, page builder custom code blocks, and checkout settings.
- Pick one owner per pixel. Decide which installation stays. Prefer the one that also covers checkout and server events.
- Remove, don't comment out in place. Commented code tends to be "restored" by the next person. Keep a backup of the removed snippet outside the theme.
- Check custom events. If the removed installation also fired AddToCart or Lead, make sure the surviving one fires them.
Removing the wrong copy can stop tracking entirely for pages that only the removed installation covered, such as checkout. Test every key page after the change.
How to verify the fix
- Clear the Network log, reload, and confirm exactly one
/trrequest withev=PageViewper pixel ID. - Place a test order or submit a test lead and confirm a single conversion request per pixel.
- Reload the confirmation page and make sure Purchase does not fire again.
- Use the Test Events tab in Events Manager to watch the same actions arrive once. Our Test Events walkthrough explains how to read the results.
Reported numbers in Events Manager will settle over the following days as new data comes in.
FAQ
Is it bad to have two different pixel IDs on one site?
No, as long as each one is intentional and owned by someone. Problems come from unknown pixels and plain track calls that send every event to every pixel when that wasn't the plan.
Events Manager shows browser and server events for Purchase. Is that a duplicate?
Not if deduplication works. Meta matches the browser eventID and the server event_id together with the event name, and keeps one. If the IDs don't match, both are counted.
Will removing the duplicate fix my past data?
No. Events already received stay in your history. Fixing the setup only affects new events, so note the date of the change when you compare reports.
Why does Purchase fire twice only for some orders?
Look at the confirmation page. Customers who reload it, return from an order email, or switch devices can trigger it again. Fire Purchase once per order ID and deduplicate with the order ID as the event ID.
