Skip to main content

What is exactly-once delivery?

Exactly-once delivery means every message reaches the receiver exactly one time: nothing lost, nothing duplicated. It is the guarantee everyone wants from a webhook system, and no webhook system can honestly provide it as a transport guarantee. What well-built systems provide instead is at-least-once delivery plus idempotent processing, which produces the thing people actually want: exactly-once effects.

Sending webhooks?
Svix is the enterprise-ready webhook sending service. It handles signing, retries, and delivery observability, so you can ship a reliable webhook platform in minutes instead of months. Start sending webhooks with Svix.

Why it's impossible over HTTP

The problem sits in one unavoidable moment. A provider sends a webhook and the response never comes back. Two things could be true: the request never arrived, or the receiver processed it and the acknowledgment was lost. From the provider's side these are indistinguishable, and each demands the opposite action. Retrying risks a duplicate if the handler already ran; not retrying risks losing the event if it didn't. A sender forced to choose without knowing has already given up one half of exactly-once.

This is a version of the Two Generals problem, and it applies to any two systems that communicate over an unreliable channel, which HTTP across the public internet certainly is. Message brokers inside a single trust boundary can get close with transactions and coordinated commits across broker and consumer state, which is what Kafka's transactional "exactly-once semantics" refers to. A webhook provider POSTing to an endpoint it doesn't control has no such transaction spanning both sides.

Exactly-once effects: the achievable version

The practical goal is that each event's side effects happen exactly once, even though its delivery may happen more than once. That splits the work in two.

The provider delivers at-least-once: persist the message, retry with backoff until acknowledged, never drop an event because a response went missing. The receiver deduplicates: track the unique message ID that arrives with each delivery, and skip processing when an ID repeats. Providers following the Standard Webhooks specification send that ID in the webhook-id header, stable across retries, and the spec recommends exactly this use of it.

Neither half works alone. At-least-once without deduplication double-charges a customer eventually. Deduplication without at-least-once has nothing to deduplicate when events silently vanish. Together they deliver what exactly-once promised, with the complexity placed where it can actually be solved, inside the receiver's own transaction boundary.

What to look for in practice

On the sending side, the questions that matter are the at-least-once ones: does the provider persist before attempting delivery, what does the retry schedule look like, and is there a dead letter queue or replay path when retries run out.

On the receiving side, treat any claim of exactly-once delivery from a webhook product with suspicion, and build the deduplication anyway. A handler that inserts with a unique constraint on the message ID, or checks a processed-IDs store before acting, is a few lines of code. It converts the retry machinery from a correctness threat into pure reliability. The idempotency and deduplication lesson walks through the patterns.

Frequently asked questions

Can webhooks guarantee exactly-once delivery?

No. When a response is lost, the sender cannot distinguish an unprocessed request from an unacknowledged one, so it must either retry (risking a duplicate) or drop (risking a loss). The achievable guarantee is at-least-once delivery, with the receiver deduplicating on the message ID to get exactly-once effects.

Doesn't Kafka have exactly-once semantics?

Within a single Kafka cluster, transactions can make produce-process-consume pipelines effectively exactly-once, because one system coordinates both the message state and the consumer offsets. That machinery does not extend to an HTTP POST against an endpoint someone else operates, which is what a webhook is.

What are exactly-once effects?

The practical substitute for exactly-once delivery: each event's side effects happen once even if the event is delivered multiple times. It is achieved by pairing at-least-once delivery from the sender with idempotent, deduplicating processing in the receiver.

Is at-most-once delivery ever the right choice?

Only when losing individual events is acceptable, such as high-frequency telemetry where the next data point supersedes the last. For anything with business meaning, a payment, a signup, a state change, losses are worse than duplicates, and at-least-once is the right default.

Ready to send webhooks?

Svix handles signing, retries, rate limiting, and delivery observability for the webhooks you send to your users, so your team can stay focused on your product.