Client-side event data is fundamentally unreliable. JavaScript errors suppress events. Ad blockers intercept requests. Bot traffic generates synthetic events. Network failures create gaps. Duplicate events arrive from tab restores and service worker replays.
The solution is server-side enrichment and validation. In your server-side GTM container or custom event pipeline, implement: IP-to-geo resolution (MaxMind), user-agent parsing (DeviceAtlas), bot detection (IAB/ABC list matching plus behavioural heuristics), event deduplication (idempotency keys with Redis TTL), timestamp validation (reject events with clock skew > 5 minutes), and referrer classification (using a maintained referrer taxonomy, not regex patterns).
This enrichment layer is the difference between defensible analytics data and data that cannot be verified.
In server-side GTM specifically, you can implement enrichment using custom templates and Cloud Functions. Create a GTM variable template that calls a Cloud Function with the incoming event data, enriches it with geo/device/bot classification, and returns the enriched payload. The GA4 tag then fires with the enriched data — all before anything reaches Google's servers.
The deduplication strategy deserves special attention. Generate a unique event_id client-side (crypto.randomUUID() or a hash of timestamp + event_name + page). On the server, store each event_id as a Redis key with a 5-minute TTL (SET with NX and EX 300); if the key already exists, the event is a duplicate — reject it silently. This eliminates the 3-8% event duplication that is common in client-side-only implementations.
Viktor Kvant
Senior Web Analyst specialising in data ownership, advanced tracking implementations, and translating data into strategic business value.
Connect on LinkedIn