Skip to content
B
BIPASHA.DEV
system boot — v1.0
$ initializing bipasha.dev0%
click or press any key to skip ↵
All posts
SystemsMay 20, 2026·1 min read

Designing Idempotent Kafka Consumers That Never Double-Process

Exactly-once is a lie you tell at scale — here's how to get effectively-once with dedup keys and a transactional outbox.

B

Bipasha Bhattacharjee

Software Engineer

When you process millions of events, retries are not an edge case — they're the steady state. The question is never if an event gets redelivered, but what happens when it does.

The problem with retries

Kafka gives you at-least-once delivery. Combine that with consumer restarts, partition rebalances, and the occasional 3am incident, and the same message will land in your handler more than once. If that handler isn't idempotent, you double-charge a customer or double-send an email.

Exactly-once delivery is mostly a marketing phrase. What you actually want is effectively-once processing — and you build that yourself.

Dedup keys

The pattern I reach for: derive a deterministic dedup key from the event's natural identity, then check it against a fast store before doing any side effect.

python
async def handle(event):
    key = f"order:{event.order_id}:{event.version}"
    # SET NX returns False if the key already exists
    if not await redis.set(key, "1", nx=True, ex=86400):
        return  # already processed — skip silently
    await charge_customer(event)

The transactional outbox

Dedup alone isn't enough when you also need to publish a downstream event. If the DB write commits but the publish fails, you're inconsistent. The outbox pattern makes the write and the publish atomic:

  • Write the business row and an outbox row in the same DB transaction.
  • A separate relay reads the outbox and publishes to Kafka.
  • Mark the outbox row sent only after the broker acks.

This turns 'exactly-once' (impossible) into 'effectively-once' (achievable), and it survives every failure mode the broker can throw at you.

#Kafka#Distributed Systems#Idempotency
Share

Keep reading

Enjoyed this?

Get new notes on systems and AI in your inbox.