Skip to content
All posts

.NET

Handling Duplicate Background Jobs in .NET with Retry-Safe Logic

Idempotency keys, transition envelopes, and the small patterns that stop background workers from doing the same work twice.

April 21, 2025 7 min readBy Arulprakash Subramanian
#Background jobs#Idempotency#Reliability

Why duplicates happen

Most durable job queues guarantee at-least-once delivery. That is the right default — losing a job is worse than running it twice. But it means your handler will, eventually, be invoked twice for the same logical work.

The transition envelope

Wrap each unit of work in an envelope that carries a stable id derived from the business event, not the queue message. On entry, the handler checks whether that id has already been processed and short-circuits if so.

This single pattern absorbs most duplicate-delivery cases without making individual handlers harder to read.

Make downstream calls survivable

When the downstream system is not idempotent, isolate the call behind a small adapter and add your own dedupe at that boundary. Log the correlation id you used so support can trace what happened.