hello@newnorth.nl+31 (0) 85 401 31 62
/Journal

Data integrity: noticing when your numbers stop adding up

ReferenceData2023.06.04
Freek Kampen
Freek KampenCo-founder, New North Digital

What breaks data integrity in a tracking setup, and how to catch a duplicate transaction or a vanished dataLayer before your client does.

What data integrity means

Data integrity is whether your numbers are right and stay right: complete, consistent and unchanged between the moment of measurement and the moment of reporting.

In a tracking setup that is not an abstract idea. It is the difference between 412 orders in your backend and 412 transactions in GA4, every day, without anyone having to look.

Most of the damage does not come from one big outage. It comes from something breaking quietly and nobody noticing for three weeks.

What breaks it in practice

  • A tag placed twice. The Google tag sits in the source and in the container, or the thank-you page fires purchase again on a refresh. Revenue doubles, conversion rate follows, and Google Ads starts bidding on it.
  • A release where the dataLayer disappears. A developer renames a field or removes a push while cleaning up. Pageviews carry on, ecommerce data does not. You often see it first as a half-empty items array.
  • A consent banner that fires earlier or later after an update. Later, and hits leak out before the status is known. Earlier, and some of your tags may never fire at all.
  • Bots and spam. GA4 filters known bots, but headless browsers and Measurement Protocol traffic get through. Look for traffic with no language, an odd referrer, or one-page behaviour at scale.
  • Time zone and currency. A property in a different time zone than your backend shifts your daily totals. Send a value on purchase without a currency and you risk the revenue being ignored. Changing the time zone only applies from that moment on, never retroactively.
  • One template without events. The new product page type or the B2B ordering flow never got the tags. Your totals are almost right, which is exactly what makes it hard to spot.

Catching it before your client does

Compare transactions daily. Put the order count from your backend next to the GA4 transaction count for the same day and express the gap as a percentage. A steady gap of a few percent is normal, caused by consent and ad blockers. A jump to 0 percent or to 90 percent deserves an alert.

Work with a deviation threshold, not with a glance. Pick a percentage that triggers a message, say more than ten percent difference, or two days running with a wider gap than usual. GA4 lets you build custom insights in the Insights panel with an email when a threshold is crossed. Coarse, and better than nothing.

Check revenue per channel for zero values. A channel with revenue yesterday and exactly zero today, while sessions hold steady, points at a broken link or a lost parameter.

Run a recurring query on your BigQuery export. The export holds every hit as it arrived, so duplicates are in there. Schedule it daily and write the result to a table your dashboard reads.

The query for duplicate transactions

SELECT
  ecommerce.transaction_id,
  COUNT(*) AS event_count,
  COUNT(DISTINCT user_pseudo_id) AS client_count,
  SUM(ecommerce.purchase_revenue) AS revenue
FROM `my-project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
                        AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
  AND event_name = 'purchase'
  AND ecommerce.transaction_id IS NOT NULL
GROUP BY transaction_id
HAVING event_count > 1
ORDER BY event_count DESC

One client behind two events means a refresh or a duplicated tag. Two clients behind the same id means your backend is reissuing transaction ids, or someone placed a test order.

Swap the project name and the property id for your own. The dataset GA4 creates is named analytics_ followed by your property id.

Monitoring instead of finding out later

This is where a tagging project differs from maintenance. An implementation is correct on the day it ships. Whether it still is four months later depends on every release, every plugin update and every tag somebody adds along the way.

So we build checks on the export rather than trusting the interface: daily counts next to the backend, a query on duplicate transaction ids, and an alert when an event that was always there goes missing.

A missing month cannot be recovered. The best you can do is explain it.

What to do with this

  • Set up one daily comparison between backend orders and GA4 transactions, as a percentage.
  • Decide the threshold that triggers an alert, and agree who acts on it.
  • Schedule the query above in BigQuery, daily, across the last seven days.
  • Check your property time zone and confirm every purchase carries a currency.
  • Walk your main page types in Tag Manager preview mode after each release, or have an automated test do it.
  • Filter out test orders and internal traffic before you draw conclusions from the numbers.

Want to talk about this?

Let's talk data.

Tell us about your stack, your goals, the data you wish you had.

Takes 1 minute