Idempotent Event Handlers: Don't Double-Count Events

An idempotent event handler ensures processing the same event multiple times has the same effect as processing it once. This is vital in event-driven systems to prevent data corruption from redelivered messages. The footgun is assuming exactly-once delivery.
Why it exists
Event-driven systems often use message queues to decouple event producers from consumers, as described in event sourcing. In these distributed systems, network issues or service restarts can cause a message queue to deliver the same event more than once. If an event handler isn't prepared for this, it can lead to critical bugs, like charging a customer twice or adding the same item to an order multiple times.
The mental model
An idempotent event handler is like a bouncer with a checklist at a private event. The first time a guest (the event) arrives with a valid ticket (the event ID), the bouncer checks their name off the list and lets them in. If the same guest tries to enter again later, the bouncer sees their name is already checked off and politely turns them away. The final state—the guest is inside—is the same whether they tried to enter once or five times. The handler ensures an event's side effect happens only once.
How it works
To achieve idempotency, a handler must first check if it has already processed a given event before executing its core logic. A common technique is to store the unique IDs of processed events in a persistent store, like a database table or a Redis set. When an event arrives, the handler checks if its ID exists in this store. If it does, the handler ignores the event and simply acknowledges it to the queue. If not, it processes the event, then atomically records the event ID in the store as part of the same transaction.
When to use it
Use idempotent handlers whenever an event triggers an action with side effects in a system with at-least-once message delivery. This is critical for handlers that modify data in a database (like updating a materialized view, as mentioned in event sourcing), call an external API that isn't idempotent itself, or send a notification like an email. Any operation that shouldn't run twice needs this protection.
When not to use it
Idempotency is less critical for operations that are naturally idempotent, such as setting a specific value (e.g., user.status = 'active'). If you have a system that truly guarantees exactly-once processing, which is rare and complex, the overhead may be unnecessary. However, for most distributed architectures that rely on message queues, building idempotent handlers is a defensive best practice.
One canonical example
In an event sourcing system, an OrderConfirmed event with ID evt_123 is published. A handler consumes this to send a confirmation email. Due to a temporary network failure, the queue redelivers evt_123. A non-idempotent handler would send a second email. An idempotent handler would first check a database for evt_123. On the first delivery, it finds nothing, sends the email, and saves evt_123 to its processed_events table. On the second delivery, it finds evt_123 and does nothing, preventing a duplicate email.
Interview question
What is the primary purpose of implementing an idempotent event handler in an event-driven system?
- a.To optimize network bandwidth by reducing the number of messages sent between services.
- b.To guarantee that each event message is delivered and processed exactly once by the message queue.
- c.To prevent the system from performing the same side effect multiple times if an event is redelivered.Correct
- d.To ensure that all events are processed in the strict order they were generated.
Why? this is the answer
The card states that an idempotent event handler ensures processing the same event multiple times has the same effect as processing it once, specifically to prevent data corruption from redelivered messages. Option C accurately reflects this. Option B is incorrect because idempotency helps the handler cope with at-least-once delivery, it does not guarantee exactly-once delivery from the message queue itself.
Just read this? Test yourself on what you have been reading.
Read the original → learn.microsoft.com
- #event sourcing
- #distributed systems
- #message queues
- #idempotency
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles