Topic: Tracking Quality

Duplicate purchases in GA4 - why they happen and how the auditor finds them

Bernhard Prange · 2026-05-19 · 5 min read

In the GA4 e-commerce reports, double the revenue suddenly appears for the same order. Three weeks later the reporting team asks why the order count does not match the shop backend. Duplicate purchase events are a classic GTM bug - and one that the auditor can find in under a minute.

What happens in the code

The check in app/queries/checks/duplicate_events.sql groups events into second buckets and marks events fired multiple times within the same session:

duplicates_marked AS (
  SELECT *,
  COUNT(*) OVER (
  PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
  ) AS duplicate_count,
  ROW_NUMBER() OVER (
  PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
  ORDER BY event_timestamp_micros ASC
  ) AS occurrence_number
  FROM events_with_bucket
)

The bucket calculation happens beforehand via TIMESTAMP_SECONDS(event_timestamp_micros / 1000000). Multiple purchase events within the same second, the same session and the same user_pseudo_id are marked as a duplicate.

Thresholds

Status Condition
Green 0 duplicates
Yellow 1-5 duplicates
Red >5 duplicates or >5 % of purchases

Typical causes

  • Double-click on the checkout button - the user clicks twice quickly, both clicks trigger an Ajax call within the same second.
  • GTM trigger fires multiple times - the purchase trigger is not set to Once per Page, or a history-change listener fires it again on top.
  • Plugin conflict - an e-commerce plugin (e.g. the WooCommerce GA4 plugin) sends the purchase in parallel with a custom GTM tag.
  • Browser retry - on network latency the browser repeats the request, the server processes both calls.
  • Incomplete Universal Analytics migration - the old UA snippet still runs alongside the new GA4 tag.

How the auditor shows it

The create_duplicate_transactions_section section in app/components/dashboard/sections/ecommerce_transactions.py delivers:

  • Warning with count and revenue impact - how many purchases are duplicated, how much revenue depends on it?
  • Summary cards for the duplicate count and affected transaction IDs.
  • Detail table with concrete transaction_id, event_timestamp, purchase_revenue and the number of repetitions.

This lets you narrow down not only the whether, but also the where - often duplicates trace back to a few trigger configurations.

How to prevent them

  1. Use transaction_id as the dedup key in GA4. GA4 itself deduplicates purchase events with an identical transaction_id for a limited time, but not reliably - so you should fix the bug at the source.
  2. Set the GTM trigger to Once per Page and make sure no parallel history-change listener fires along with it.
  3. Plugin audit - if your shop has a dedicated e-commerce plugin, check whether it sends purchases in parallel with your custom tracking.
  4. Idempotency in server-side tagging - if your SST setup reacts to retries, make sure identical transaction_id calls within, say, 60 seconds are discarded.
  5. In the auditor, check again after 24 h under E-commerce checks.

Frequently asked questions

How do I find duplicate transactions in GA4?
The GA4 Auditor groups purchase events from the BigQuery export into second buckets per session and user_pseudo_id and marks multiple firings. This shows you the count, the affected transaction_id and the revenue impact - instead of just a suspicious total number.
Why do duplicate purchase events happen?
The most common causes: double-click on the checkout button, a GTM trigger without 'Once per Page', e-commerce plugins sending in parallel, browser retries on latency and an incomplete migration from Universal Analytics where the old snippet still runs alongside.
Does GA4 deduplicate based on the transaction_id?
GA4 deduplicates purchase events with an identical transaction_id for a limited time, but not reliably. You should fix the bug at the source - set the GTM trigger to 'Once per Page', resolve plugin conflicts and react idempotently to retries in server-side tagging.

ecommerce duplikate transaction-id gtm

Related articles