Duplicate conversions are one of the most common — and most damaging — problems in a GA4 implementation. When your data shows 400 purchases but your Shopify backend shows 200, every decision downstream is built on a lie: inflated ROAS, misleading CPAs, and channel attribution that points you in the wrong direction.

The good news: once you know the three root causes, fixing it is usually straightforward. This guide walks through each one with a diagnostic checklist and the exact steps to resolve it.

Before you start: open your GA4 DebugView (Admin → DebugView) in one tab and your live site in another. You'll need to watch events fire in real time as you test.

The three causes of duplicate conversions

Almost every case of duplicate conversions in GA4 traces back to one of these three places. Identify which one applies to you before making any changes.

Cause 01

GTM tag firing twice

A GA4 event tag has two triggers — or the trigger fires on both a pageview and a custom event — so one user action sends the event twice.

Cause 02

Duplicate GA4 base tags

Your site has the GA4 config tag in GTM and hardcoded in the page source. Every event fires once through GTM and once through the hardcoded snippet.

Cause 03

Thank-you page reloads

The order confirmation or thank-you page can be refreshed or revisited, re-firing the purchase event each time without any deduplication logic.

Cause 04

Missing transaction ID

GA4 can deduplicate purchase events automatically — but only if you pass a unique transaction_id. Without it, every hit is treated as a new conversion.


Step 1 — Diagnose which cause you have

Open GTM Preview mode (Preview → Connect), then complete a test conversion on your site. In the GTM debug panel, look at the Tags tab for your conversion event.

  1. If the tag shows Fired more than once for a single trigger event → Cause 1 (multiple triggers).
  2. If the tag fires once in GTM but you see the event twice in GA4 DebugView → Cause 2 (duplicate snippet).
  3. If the event fires correctly the first time but then again on page refresh → Cause 3 (thank-you page).
  4. If you're seeing inflated numbers but the event only fires once per session → Cause 4 (missing transaction ID).

You can also check in GA4 directly: go to Reports → Realtime, complete a test conversion, and count how many times the event appears. If it shows up twice within seconds of a single action, you have duplication at the firing level (Cause 1 or 2).

Fix 1 — GTM tag firing twice

In GTM, open your GA4 event tag for the conversion (e.g. purchase or generate_lead). Scroll to the Triggering section.

Common mistakes to look for:

  • Two separate triggers attached to the same tag (e.g. a Page View trigger and a Custom Event trigger both attached).
  • A trigger set to fire on All Pages when it should only fire on a specific URL.
  • An event-based trigger with no conditions, so it fires on every custom event pushed to the dataLayer — not just the intended one.

The fix is to keep exactly one precise trigger per event tag. For a purchase event, the trigger should be a Custom Event trigger matching the event name exactly:

GTM — Custom Event trigger config

Trigger type:   Custom Event
Event name:     purchase
This trigger fires on:  All Custom Events

Remove any secondary triggers. If you intentionally need the tag to fire in multiple scenarios, create separate tags for each — don't stack triggers on one tag.

Fix 2 — Duplicate GA4 base tag

This is the most common cause we see after UA-to-GA4 migrations. The developer added the GA4 snippet directly to the site's <head>, and GA4 is also firing through GTM. Both initialise the same Measurement ID, so every event fires twice.

To check: view your page source (right-click → View Page Source) and search for your Measurement ID (e.g. G-XXXXXXXXXX). If it appears in the raw HTML and you have a GA4 Configuration tag in GTM, you have a duplicate.

The fix: choose one method and remove the other. GTM is the preferred approach because it's easier to manage and debug. Remove the hardcoded snippet from your site template or <head> tag and let GTM handle the initialisation entirely.

Check with your developer before removing the hardcoded snippet. Some platforms (Shopify, WordPress plugins) reinject it automatically. If so, you may need to suppress it at the plugin level, or use GTM's built-in GA Settings Variable to control which pages initialise GA4.

Fix 3 — Thank-you page reloads

If a user bookmarks the confirmation page, hits the back button and resubmits, or simply refreshes, your purchase tag fires again. The solution is to gate the conversion tag behind a session flag that's set when the event first fires.

In GTM, add a 1st Party Cookie variable and a Custom HTML tag that sets a cookie once the purchase event fires. Then add an exception trigger to your conversion tag so it only fires when that cookie is not set.

  1. 1
    Create a 1st Party Cookie variable In GTM: Variables → New → 1st Party Cookie. Name it purchase_fired. Cookie Name: purchase_fired.
  2. 2
    Create a Custom HTML tag to set the cookie Add a Custom HTML tag that fires on your purchase trigger. It sets the cookie with a short expiry so repeat visits later are still tracked.
  3. 3
    Add an exception to your conversion tag On your GA4 purchase event tag, add an Exception trigger: fire when {{purchase_fired}} equals true. This blocks the tag from firing if the cookie already exists.

Custom HTML tag — set the deduplication cookie

<script>
  // Set a session cookie so the purchase tag won't fire again on refresh
  document.cookie = "purchase_fired=true; path=/; max-age=1800; SameSite=Strict";
</script>

The max-age=1800 value expires the cookie after 30 minutes — long enough to block a refresh, short enough that a genuinely new purchase in the same session will still be tracked.

Fix 4 — Add a transaction_id for automatic deduplication

For purchase events specifically, GA4 has built-in deduplication — but it only works if you pass a unique transaction_id parameter. If two purchase events arrive with the same transaction ID within a short window, GA4 discards the duplicate automatically.

Push the transaction ID into your dataLayer from your backend (order management system, Shopify checkout, etc.) alongside the other ecommerce parameters:

dataLayer push — purchase event with transaction_id

dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'ORDER-10042',  // unique per order
    value: 149.00,
    currency: 'GBP',
    items: [
      {
        item_id: 'SKU-001',
        item_name: 'GA4 Audit Template',
        price: 149.00,
        quantity: 1
      }
    ]
  }
});

Best practice: even if you implement the cookie method above, always pass a transaction_id. The two approaches complement each other — the cookie blocks client-side re-fires, while the transaction ID catches any edge cases that slip through to GA4's servers.

Step 2 — Verify the fix in DebugView

After making your changes, publish your GTM container and test again end-to-end before confirming the fix is working:

  1. Open GA4 DebugView and filter to your test device.
  2. Complete a test conversion on your site.
  3. Confirm the conversion event appears exactly once in DebugView.
  4. Refresh the thank-you or confirmation page and verify the event does not fire again.
  5. Check the event parameters — confirm transaction_id is present and correct.

Give it 24–48 hours after publishing before drawing conclusions from your main GA4 reports. Realtime data reflects fixes immediately; historical reports aggregate more slowly.

Step 3 — Set up an ongoing sanity check

One-off fixes are valuable, but conversion accuracy should be monitored regularly. The simplest way to do this is a BigQuery query that compares GA4 conversion counts against your source-of-truth backend data on a weekly basis.

If you don't have a BigQuery pipeline yet, a low-tech alternative is to export GA4 conversion counts to a Google Sheet weekly and compare them to your CRM or ecommerce platform's order count. A consistent ratio above 1.1 (10% more GA4 conversions than actual orders) is a signal to investigate.

Bonus: In GA4, go to Admin → Conversions and check whether any events are marked as conversions that shouldn't be. A common mistake is marking session_start or page_view as a conversion, which massively inflates your numbers.


Duplicate conversions are fixable — but they're also a symptom of a broader implementation health problem. If you're seeing them, it's worth auditing your full GA4 setup to find other data quality issues before they compound into bigger reporting problems.

Not sure which cause applies to you?

We offer a free 30-minute GA4 audit where we'll diagnose your exact setup, identify any conversion tracking issues, and tell you exactly what needs fixing — no obligation.