Say your order table shows 1,412 orders last month and GA4 shows 1,196. Someone will propose rebuilding the tracking. That is usually wrong: several common causes are not tracking defects but definition mismatches, report-level suppression, or documented platform behaviour. Google's own documentation states that Analytics deduplicates purchase events sharing a transaction ID, and that sending an empty transaction_id string causes all purchase events to be deduplicated. One templating bug produces a chart that looks like catastrophic data loss.
This guide is for whoever owns a GA4 ecommerce property and has a gap nobody can explain. By the end you will be able to run eight ordered checks, each with a test and a threshold, and name which branch owns your gap before anyone touches a tag.
Branch 0: align the comparison before you measure the gap
Most reconciliations fail here. GA4 timestamps a purchase when the event fired; your order table timestamps a row when it was written, so an order placed at 23:58 and written at 00:02 lands on different days.
Fix four alignments first: the timezone (GA4 uses the property's, your database probably stores UTC), the window boundary, the definition (your order table likely excludes cancellations and failed payments while GA4 counts every event that fired), and the row grain. Then re-run on a clean seven-day window. If the gap moves by more than a third, part of what you were chasing was never in the data.
Branch 1: does the purchase event fire on every path to an order?
List every route that writes a row to your order table: web checkout, express and wallet checkout, native app, subscription renewals, phone or in-store orders, back-office manual orders, and B2B quotes converted to orders. Any route that never loads your web container cannot emit a purchase event.
Test: segment the order table by order source and compute GA4 coverage per source. A source near 0% coverage is a missing implementation, not loss. Threshold: if one source accounts for more than half your gap, stop and go implement. This is the cheapest branch to confirm, and the one teams skip.
Branch 2: are duplicates collapsing your count, or inflating it?
Google documents that Analytics deduplicates purchase events with the same transaction ID, that the same ID should not be reused across users, and that an empty string collapses every purchase event. It publishes no deduplication window. That gives two opposite failure modes: a static or empty ID crushes your count toward one, while a missing ID on an event that refires when the customer reloads the confirmation page inflates it.
Test: in the BigQuery export, count purchase events grouped by transaction_id. A tail of two or three events per ID means refresh duplication; one ID carrying hundreds is a templating bug. Because no window is published, do not assume deduplication holds across a long backfill.
Branch 3: is consent stopping collection, and is modeling covering it?
With analytics_storage denied, Google says cookieless pings are still sent, no Analytics cookies are set or read, and those pings feed modeling. Modeling is not automatic. Its documented prerequisites are at least 1,000 events per day with analytics_storage='denied' for at least 7 days, and at least 1,000 daily users sending events with analytics_storage='granted' for at least 7 of the previous 28 days. Google adds that meeting both still does not guarantee eligibility.
Test: take your denial rate from your consent platform's logs, not from GA4, then check the property against both thresholds. Threshold: a property below either one carries the full loss and receives none of the modeling, which describes most mid-market properties in this region. Google has also published that from 15 June 2026, Google Ads cookie and ID collection follows Consent Mode rather than Google Signals, so verify this branch against current documentation.
Branch 4: is the browser fragmenting identity rather than dropping events?
WebKit documents that Intelligent Tracking Prevention deletes JavaScript-created cookies and other script-writeable storage after 7 days without interaction, caps JavaScript cookies written on a landing page to 24 hours when it detects link decoration, and caps Set-Cookie to 7 days behind a third-party CNAME or IP address. None of that deletes a purchase event that already fired; it fragments the user and session the event belongs to.
Test: compare purchase event counts against purchasing-user counts, split by browser. If events hold steady while user counts inflate on Safari, this is your branch, and the fix is server-set first-party cookies rather than a tracking rebuild.
Branch 5: is the interface hiding rows the dataset still contains?
Google states that data thresholds are system-defined and cannot be adjusted, and that rows may be withheld when a report includes demographic data or audiences built from it, when search-query rows have too few users, or when counts are low inside a narrow date range. Separately, sampling may occur once a query exceeds 10 million events for standard properties, and up to 1 billion for Analytics 360.
Test: run the same count against the daily BigQuery export, which Google describes as raw, unsampled, last-click-observed, with no modeling. Threshold: if BigQuery matches your order table and the GA4 interface does not, nothing was lost. It was suppressed or sampled at query time.
Branch 6: how much is actually lost in transport?
Blockers, network failures and tags that never execute are real. The 10% to 30% loss range repeated across vendor content is not traceable to a primary measurement, so we do not treat it as a planning input. Neither should you.
Test: compare your server's count of successful order confirmations against purchase events arriving in GA4, daily, segmented by country and device. That ratio is your first-party loss figure, specific to your stack, and the only one worth budgeting against.
[INTERNAL DATA NEEDED: observed GA4-to-backend purchase coverage range across Switas client properties, split by EU and Türkiye traffic, to replace the unverifiable industry range with a sourced one.]
Branch 7: can the gap be repaired, and for how long?
The Measurement Protocol can send purchases server-side, with a hard limit: Google documents that events can be backdated up to 72 hours. Past that, the default setting accepts the item but resets its timestamp to 72 hours ago, and ENFORCE_RECOMMENDATIONS rejects it outright. Events meant to join client-side gtag events should arrive within 48 hours.
So a gap older than three days cannot be repaired inside GA4, only documented. Decide which you are building: an automated repair inside the 72-hour window, or a reconciliation record in your warehouse. Most teams need the second.
The branch table
| Branch | Test to run | Documented threshold | Verdict if it fires |
|---|---|---|---|
| 0. Comparison | Re-run on aligned timezone, window, definition | Gap moves >33% | Not a tracking defect |
| 1. Missing paths | Coverage per order source | Any source near 0% | Implementation gap |
| 2. transaction_id | Events grouped by ID in BigQuery | >1 event per ID, or 1 ID with many | Dedup collapse or inflation |
| 3. Consent | CMP denial rate vs modeling prerequisites | 1,000 denied events/day, 7 days | Uncovered consent loss |
| 4. Browser identity | Events vs users by browser | 7-day and 24-hour ITP caps | Identity fragmentation only |
| 5. Reporting layer | Same count in daily BigQuery export | 10M events per query (standard) | Suppression or sampling |
| 6. Transport | Server confirmations vs GA4 events by country | Your own measured ratio | Genuine collection loss |
| 7. Repair window | Age of the oldest gap you need back | 72 hours backdating | Repairable, or warehouse-only |
One property, two loss regimes: the regional wrinkle
Google's EU user consent policy applies, in its own words, to end users located in the EEA, the UK and Switzerland, and for that traffic advertisers are required to send consent signals via consent mode or the TCF. Türkiye sits outside that scope, so Google's consent-signal requirement does not reach a Turkish property through those terms. Turkish law still does: the KVKK's cookie guidance requires explicit consent for non-essential cookies, and in decision 2022/1358 of 23 December 2022 the Board fined a data controller 300,000 TRY for running non-essential cookies without explicit consent or adequate disclosure.
So a property serving both markets holds two collection regimes in one dataset, and a property with no consent gate shows better GA4 coverage than an EU peer for reasons unrelated to tag quality. Run Branches 3 and 6 per market, and never report one company-wide coverage number.
What this does not cover, and where it breaks down
Counts, not credit. This reconciles how many purchases exist, not which channel should get credit. Attribution mismatches between GA4, Google Ads and your backend are a separate problem.
It assumes a BigQuery export. Without it, Branches 2 and 5 lose their only reliable test. Standard properties also carry a documented daily export limit of 1 million events, so high-volume properties need filtering first.
It breaks down at low volume. Below roughly a few hundred orders a month, day-level variance exceeds the gap you are chasing. It is also not legal advice: the KVKK and EU points explain data loss, not compliance obligations.
FAQ
Does GA4 model the purchase events it loses to consent denial?
Google's documentation describes modeling as applying to user, session and new-user counts in standard reports under the Blended reporting identity, and names page_view, first_visit and session_start as event counts it does not apply to. It does not state that purchase event counts are modeled, so do not assume modeling closes a purchase-count gap.
Does the BigQuery export fix the gap?
No, it diagnoses it. The daily export gives raw, unsampled, unmodeled event data, which separates genuine collection loss from interface-level suppression, but it cannot recover an event that never reached Google.
Does server-side tagging recover consent-denied purchases?
Not by itself. It helps with cookie lifetime and lets you set first-party cookies properly, which addresses Branch 4, but it does not create permission you do not have: a denied analytics_storage signal still has to be honoured.
Does transaction_id deduplication have a time limit?
Google's documentation does not publish one; it states only that Analytics deduplicates purchase events with the same transaction ID. Treat that as a known unknown and design IDs to be globally unique.
How large a gap is normal?
There is no credible published benchmark, and the figures circulating in vendor content are not traceable to a primary source. Measure your own server-confirmation-to-GA4 ratio per country: a stable ratio is healthy, a drifting one is the alarm.
Do we need consent mode if we only sell in Türkiye?
Google's EU user consent policy covers the EEA, the UK and Switzerland, so its signal requirement does not extend to Türkiye-only traffic, though Turkish cookie rules under the KVKK are a separate obligation and have been enforced with fines. Either way, whatever gate you run changes your loss profile, so measure it rather than infer it.
Run it, or have us run it
Work through the eight branches on your own property and write down which one owns your gap. If you would rather have it done properly, with the BigQuery queries, the per-market consent split and the server-side repair decision handed over as something your developers can act on, our data analytics services team runs this audit.
Sources
- [GA4] Minimize duplicate key events with transaction IDs — Google Analytics Help
- [GA4] Behavioral modeling for consent mode — Google Analytics Help
- [GA4] Consent mode — Google Analytics Help
- [GA4] About data thresholds — Google Analytics Help
- [GA4] How data is stored and displayed (sampling) — Google Analytics Help
- [GA4] BigQuery Export — Google Analytics Help
- [GA4] Upcoming changes to Google Analytics data controls with Google Ads — Google Analytics Help
- Send Measurement Protocol events to Google Analytics — Google for Developers
- Tracking Prevention in WebKit — WebKit
- Fix issues with your EU User Consent Policy consent audit — Google Ads Help
- Çerez Uygulamaları Hakkında Rehber — Kişisel Verileri Koruma Kurumu (PDF)
- Karar Özeti 23/12/2022, 2022/1358 — Kişisel Verileri Koruma Kurulu







