Situation: Our event table contains exact timestamps but client-side retries created duplicate rows (same user action recorded multiple times). This biased KPIs like DAU and conversion rates.Identify duplicates:- Explore patterns: group by user_id, event_type, event_timestamp, event_properties hash.- Visual checks: histogram of inter-event intervals per user; spikes near zero indicate retries.- SQL to surface candidates:sql
SELECT user_id, event_type, event_time,
COUNT(*) AS cnt,
MIN(id) AS first_id,
ARRAY_AGG(id ORDER BY id) AS ids
FROM events
GROUP BY user_id, event_type, event_time_bucket -- see dedupe rule
HAVING COUNT(*) > 1;
Deduplication rule (balance FP vs FN):- Use a conservative rule that removes obvious retries but keeps legitimate quick repeated actions.- Example rule: consider events duplicates if they have same user_id, event_type, and identical key properties (hash of payload) and occur within a short window (e.g., <= 2 seconds). Keep the earliest event_id.- Implement as idempotent pipeline step. SQL example:sql
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY user_id, event_type, properties_hash, DATE_TRUNC('second', event_time)
ORDER BY event_time ASC, event_id ASC
) AS rn,
event_time - LAG(event_time) OVER (PARTITION BY user_id, event_type ORDER BY event_time) AS delta
FROM events
)
DELETE FROM events WHERE rn > 1 AND delta <= INTERVAL '2 seconds';
- Rationale: 2s window minimizes false positives (legitimate repeated clicks rarely identical payloads within 2s) while removing most retry duplicates. Use properties_hash to avoid collapsing distinct actions.Validation & metrics:- Before/after compare totals, unique users, conversion funnel by cohort and time-of-day.- Estimate residual duplicates by sampling events with identical hashes and delta between 2–30s.- Track rollback risk: compute percent of removed events vs total and spot-check a stratified sample.Communicating residual risk to PMs:- Provide clear summary: what was removed, why, and quantitative impact (e.g., "We removed 1.8% of events; conversion rate changed from 4.2%→4.1%").- Share uncertainty: estimate residual duplicates (e.g., 0.2–0.5%) and potential effect on top KPIs.- Recommend mitigation: add client-side idempotency keys, server-side dedupe using event_id, add ingestion-level validation.- Offer dashboards showing both raw and deduped metrics for 30 days so PMs can understand differences and decide which to trust for decisions.This approach is conservative, measurable, and provides product teams with the data and context to accept the deduped metrics while planning longer-term fixes.