Idempotency
Prevent duplicate side effects with consume-scope idempotency keys.
AI workflows do side effects (charge a card, send an email, write to DB, call a vendor API). DriftQ uses at-least-once delivery via redelivery — which is great for reliability, but risky for side effects.
Goal: allow redelivery for reliability, while preventing duplicate side effects. That’s what idempotency is for.
What “consume-scope idempotency” means
DriftQ supports consume-scope idempotency keys. In plain terms: the idempotency key is treated like a “work identity” that can be safely retried without being executed twice.
- The producer sets
envelope.idempotency_key - The broker leases that key to an
ownerwhile the message is in-flight - On
ack, the key becomes committed (officially “done”)
Lifecycle: lease → ack
Consumer calls
/v1/consumewithownerand gets a message.If the message has
idempotency_key, DriftQ leases the key to that owner for the duration of the message lease.The consumer performs the side effect (or its workflow step).
Consumer calls
/v1/ackwith the sameowner.DriftQ commits the key: future redeliveries with the same key are treated as already done.
Key idea: “leased” prevents two consumers from doing it at the same time, and “committed” prevents doing it again later.
Why it matters
Without idempotency, retries can accidentally do real damage:
- double charging
- duplicate emails / notifications
- duplicate DB writes
- duplicated “tool calls” in agent workflows
Bottom line: at-least-once delivery is non-negotiable for reliability. Idempotency is how you make it safe.
Practical guidance
Use an idempotency key that uniquely identifies the side effect (ex:
invoice:{id}:charge).Keep it stable across retries — don’t generate a new key per attempt.
If you have multiple side effects, use multiple keys (one per step) or encode step identity in the key.
Example key
If the side effect is “charge invoice 781”
idempotency_key = "invoice:781:charge"Every retry of that same work uses the exact same key.
