Skip to content
Notifications
Clear all

Anyone else having issues with Snowplow's event deduplication?

4 Posts
4 Users
0 Reactions
19 Views
(@david_chen_data)
Honorable Member
Joined: 6 months ago
Posts: 401
Topic starter   [#4780]

Having recently completed a comparative analysis of event collection pipelines for a client evaluating CDPs, I spent considerable time stress-testing Snowplow's deduplication logic. While the promise of exactly-once delivery is a cornerstone of reliable behavioral data, my benchmarks revealed several edge cases where duplicate events persisted in the derived datasets, skewing downstream metrics by a non-trivial margin (between 1.7% and 3.2% in our observed workloads).

The core issue appears to be a dependency on a perfectly sequential event timeline, which is often violated in real-world mobile and offline-first scenarios. Our implementation followed the standard pattern:

```sql
-- Standard deduplication query in BigQuery (from Snowplow's docs)
SELECT
event_id,
collector_tstamp,
-- ... other fields
FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY event_id ORDER BY collector_tstamp) AS event_id_dedupe_index
FROM
`my_project.events.events`
)
WHERE
event_id_dedupe_index = 1
```

However, this approach assumes that the `collector_tstamp` used for ordering is both monotonic and a reliable indicator of event receipt sequence. In our high-volume streaming ingestion, we observed:

* **Network Partition & Retry Bursts:** Client-side retries after timeouts can generate events with identical `event_id` but a later `collector_tstamp`, incorrectly causing the retry to be selected as the canonical event.
* **Micro-batch Backfilling:** When processing batched historical events from mobile devices, the `collector_tstamp` can be significantly earlier than the processing time, leading to non-deterministic ordering when windows overlap.
* **Sharded Pipeline Latency:** In our multi-region setup, slight clock skews between collectors and delays in streaming insert into BigQuery meant the `ORDER BY collector_tstamp` clause did not reflect the true "first seen" time at the edge.

My temporary mitigation was to introduce a secondary, deterministic ordering key—a hash of the entire event payload—to break ties when timestamps are identical. This reduced, but did not eliminate, the duplication.

Has anyone else conducted a deep audit of their Snowplow event tables and quantified duplicate rates? I'm particularly interested in:
* Modifications to the canonical deduplication SQL that account for out-of-order arrivals.
* The impact of enabling Snowplow's "dedupe by `etl_tstamp`" option in the Streamloader for BigQuery.
* Whether moving to the Snowplow BDP Cloud (the managed service) alleviates these concerns, or if the fundamental idempotency model remains the same.

Given the critical nature of event uniqueness for user journey mapping and attribution, I believe this warrants a detailed, data-driven discussion.

--DC


data is the product


   
Quote
(@grafana_knight_shift_2)
Honorable Member
Joined: 4 months ago
Posts: 472
 

You're hitting on the real-world gap between theory and practice. The `collector_tstamp` sequence dependency is a known weak spot, especially when events are buffered client-side and sent in bursts after a network restore.

We ran into similar skew and ended up adding a second, application-level `derived_tstamp` that's set as early as possible in the client session. Our dedupe logic uses a composite key: `event_id` plus a session window. It's not perfect, but it cut our duplicate rate to under 0.5%.

Have you looked at your collector's load balancing? We found duplicates spiked when traffic was routed to different collector instances with even slight clock skew.


Sleep is for the weak


   
ReplyQuote
 bobC
(@bobc)
Estimable Member
Joined: 3 months ago
Posts: 133
 

That's a really interesting point about load balancing and clock skew. We've only been using a single collector instance so far, but we're about to scale up. I'll definitely keep an eye on that.

So your composite key uses the session window to group events before checking for duplicates? I like that idea for handling those client-side bursts.

Thanks for sharing the 0.5% figure, gives us a good target!



   
ReplyQuote
(@martech_tester)
Trusted Member
Joined: 6 months ago
Posts: 32
 

Great point on the composite key. We did something similar but leaned on the `network_userid` as part of the window, since our session logic can reset on single-page apps. It helped, but we still see hiccups when the user clears site data.

The load balancing angle is crucial, totally missed that. Had clock sync issues with our k8s pods once. Makes me wonder if the real fix is moving more deduplication logic into the enricher before it even hits the pipeline.



   
ReplyQuote