Module 20 ยท Task Queues & Events โ Lesson 3 of 4 ยท ~8 min
Idempotency
At-least-once means every handler must survive running twice
Lesson 2's quiz landed on the real consequence of at-least-once delivery: your task function WILL, eventually, run twice for the same job. That's not a bug to eliminate โ it's a property of every queue built on a broker like Redis. The fix isn't trying to make delivery exactly-once (that's a much harder, slower guarantee most systems don't actually need); it's making every handler idempotent โ safe to run twice, three times, with the same end result as running it once.
Three moves, from weakest to strongest:
- Natural idempotency. Design the operation so replay is harmless by construction.
UPDATE bookings SET status = 'emailed'run twice leaves the same row in the same state.UPDATE bookings SET email_count = email_count + 1run twice does NOT โ that's a counter, and counters are the classic non-idempotent trap. - An idempotency key with a unique constraint. When the operation itself can't be made naturally safe (sending an email can't be "set a flag" โ the email either goes out or it doesn't), record that this specific job already ran, using a column the database enforces uniqueness on.
- Check-then-act is NOT enough on its own โ covered next.