Event deduplication

Making retries and repeated deliveries count as one event, so one purchase, signup, or click does not appear two or five times.

why did this event fire twicestop counting the same purchase twiceone order but the report says twodouble tracked clicksthe webhook keeps repeatingevent dedublicationremove repeated eventsone action showing up multiple times

See it

Live demo coming soon

What it is

Event deduplication makes repeated deliveries of the same logical event count once. Repeats are normal: a browser handler can attach twice, a client can retry after a timeout, and webhook systems commonly promise at-least-once delivery rather than exactly once. Give the original event a stable id, carry that id through every retry, and let the receiver reject an id it has already accepted. Meta builds this into its spec: send the same event_id from the pixel and the Conversions API and the two copies collapse into one.

Reach for it anywhere retries or money are involved, especially checkout events, subscription webhooks, offline queues, and CDP forwarding. The durable version is a unique constraint or idempotency record in the same transaction as the side effect. A short in-memory set can reduce noise, but it forgets on restart and does not protect two workers racing each other.

Gotcha: deduplication needs sameness, not similarity. Hashing a payload can collapse two legitimate purchases for the same amount, while generating a new UUID on every retry makes every copy look new. Use the producer's stable event id, define how long ids are retained, and measure rejected duplicates separately. Debouncing rapid clicks is a UI behavior; it is not a substitute for receiver-side deduplication.

Ask AI for it

Make this Stripe webhook consumer idempotent using Stripe's event.id as the deduplication key. Add a Postgres table with a UNIQUE constraint on provider_event_id, insert the receipt and apply the business side effect in one transaction, and use INSERT ... ON CONFLICT DO NOTHING RETURNING id so that the side effect runs only when the insert returns a row and a racing worker gets zero rows. Return a 2xx response for an already processed event, preserve failed attempts for retry, record duplicate_count as an internal metric, and add tests for sequential duplicates, concurrent duplicates, and two distinct Stripe events with identical payload fields.

You might have meant

event trackingtracking planevent taxonomydata pipelinecdp