Marketing Data QA Processes
Tracking breaks silently, and dashboards don't complain
A dashboard will keep rendering a clean chart even when the tracking feeding it has been broken for a week — a tag that stopped firing after a site redesign, a GTM trigger condition that no longer matches the new DOM, a GA4 event parameter that got renamed in a code deploy. The chart doesn't show an error; it shows a lower number, or a flat line, and unless someone is specifically looking for that drop, the first person to notice is often a stakeholder asking why conversions crashed — weeks after the actual break. A deliberate QA process exists to catch the break before that conversation happens, not after.
Pre-launch tracking validation
Before any site change, campaign launch, or new tracking implementation goes live, a pre-launch validation pass should confirm the tags actually fire, fire with the correct parameters, and fire exactly once per intended action (not zero times, and not duplicated). The standard toolkit for this is GTM's Preview mode paired with GA4's DebugView, which shows events landing in GA4 in near real time as you trigger them manually — this is the step that catches a trigger condition that looks correct in GTM's UI but doesn't actually match the live page's markup.
Pre-launch tracking validation checklist:
[ ] GTM Preview mode: confirm every expected tag fires on the
target page/action, and no unexpected tag fires alongside it
[ ] GA4 DebugView: confirm event_name and every expected
event_param appear with correct values (not blank/undefined)
[ ] Fire count check: trigger the action once, confirm exactly
one event lands (catches double-fire from duplicate triggers)
[ ] Cross-device/cross-browser spot check: Safari and a mobile
browser specifically, since consent and ITP behavior differs
[ ] Consent mode check: confirm tags respect consent state
(no firing before consent, correct behavior after denial)
[ ] Revenue/value parameter sanity check: confirm numeric fields
(value, currency) aren't passing as strings or blankA tag that fires is not the same as a tag that fires correctly
value as an empty string, or a transaction_id that's hardcoded from the testing session and never updated, will silently corrupt every revenue report downstream while looking completely fine in a cursory Preview-mode check. Always inspect the actual parameter values, not just whether the tag fired.Automated data quality checks, running continuously
Pre-launch validation catches problems at the moment of change; it can't catch a tag that breaks later for an unrelated reason — a third-party script conflict introduced by a different team, a CMS update that alters page structure, a cookie consent banner update that changes default consent state. Continuous automated checks close that gap by running on a schedule against production data and flagging anomalies without a person having to remember to look.
-- Scheduled query: flag any key event whose daily volume
-- drops more than 40% vs. its trailing 7-day average
WITH daily_counts AS (
SELECT
DATE(TIMESTAMP_MICROS(event_timestamp)) AS event_date,
event_name,
COUNT(*) AS events
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN
FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 8 DAY))
AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
AND event_name IN ('purchase', 'generate_lead', 'sign_up')
GROUP BY event_date, event_name
),
rolling AS (
SELECT
event_name,
event_date,
events,
AVG(events) OVER (
PARTITION BY event_name
ORDER BY event_date
ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING
) AS trailing_avg
FROM daily_counts
)
SELECT *
FROM rolling
WHERE event_date = CURRENT_DATE() - 1
AND events < trailing_avg * 0.6Anomaly checks need a baseline that accounts for normal seasonality
Pre-launch validation vs. continuous automated QA
| Dimension | Pre-launch validation | Continuous automated QA |
|---|---|---|
| When it runs | Before a specific change ships | On a schedule, independent of any known change |
| Catches | Breaks introduced by the change being tested | Breaks from unrelated causes (third-party scripts, CMS updates) |
| Method | Manual Preview mode / DebugView inspection | Scheduled SQL anomaly checks, alerting |
| Who's responsible | Whoever ships the change | A standing process, usually analytics/data team owned |
| Failure mode if skipped | Broken tracking ships silently with the change | Breakage goes unnoticed until a stakeholder flags it |
Making QA a release gate, not a courtesy check
The processes above only prevent damage if they're enforced as a required step rather than an optional best practice someone does when they remember. The most durable version of this is a QA checklist embedded directly into the deploy or campaign-launch process — a checkbox a release can't ship past — paired with an alerting channel (Slack, email) that the automated anomaly checks post to automatically, so a volume drop is visible within a day rather than discovered whenever someone happens to open the dashboard.
What's next
Clean, validated tracking data is the precondition for everything else in this track — the BigQuery cost optimization module assumes the underlying event data QA'd here is trustworthy before building scheduled queries and materialized views on top of it.
Next: BigQuery Cost Optimization →
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.