# How Should You Design Webhook Idempotency for Reliable IP Registry Events?

iprs.cloud · September 24, 2026

> What Does Webhook Idempotency Actually Mean? Webhook idempotency is the property that allows the same event to be delivered more than one time without...

## What Does Webhook Idempotency Actually Mean?

Webhook idempotency is the property that allows the same event to be delivered more than one time without causing the same business operation to be performed more than once. A webhook sender may retry a request after a timeout, a sender may deliver an event to two endpoints during a migration, or a receiver may process an event successfully and then lose the acknowledgement before it reaches the sender. In each case, the receiver needs a way to distinguish a genuine new event from a repeated delivery of an earlier event. That distinction is different from ordinary duplicate detection: duplicate detection asks whether two records resemble each other, while idempotency asks whether the same logical operation has already been applied.

**Also worth reading:** [How do you build a reliable IP registry vendor comparison matrix for B2B intellectual property rights management?](https://iprs.cloud/knowledge/how_do_you_build_a_reliable_ip_registry_vendor_comparison_matrix_for_b2b_intellectual_property_rights_management.php) · [What Webhook Error Handling Strategies Should IP Registry Teams Adopt in 2026?](https://iprs.cloud/knowledge/what_webhook_error_handling_strategies_should_ip_registry_teams_adopt_in_2026.php) · [What is an AI patent auditability registry architecture and how do you design it for IP counsel and product teams?](https://iprs.cloud/knowledge/what_is_an_ai_patent_auditability_registry_architecture_and_how_do_you_design_it_for_ip_counsel_and_product_teams.php)

A practical design usually combines three elements: a stable event identifier, a durable record of processed identifiers, and an operation that can safely run again. The identifier might be an event UUID, a provider event ID, or a sender-defined key such as tenant_id:event_type:object_version. The record should include the identifier, tenant, event type, processing status, first-seen time, last-received time, and the resulting resource or operation reference. A database uniqueness constraint on the tenant and event key is usually stronger than an application-level check that can race when two workers receive the same event at the same moment.

Idempotency does not mean ignoring every message that arrives twice. A receiver should still validate the payload, authenticate the request, check whether the event belongs to the expected environment, and decide whether an already-completed event is an exact replay or a conflicting reuse of the same key. The same identifier with a different payload should normally be quarantined and investigated rather than silently accepted. For an intellectual-property registry platform, this matters when a repeated filing.created event could create duplicate family records, or a repeated renewal.processed event could trigger a second customer notice and accounting entry.

## Why Retries and Duplicate Delivery Happen

Webhook delivery is an at-least-once process in many production architectures, even when the provider describes delivery as automatic retries. A receiver that returns a 2xx response before committing its database transaction can create a false failure: the sender records success incorrectly only if the response arrives, while a crash between processing and acknowledgement causes the sender to retry. Network proxies, TLS termination, mobile clients, and load balancers also produce timeouts where the request may have reached the server even though the client never received a response. The sender cannot reliably infer from a timeout whether the business operation occurred.

Retry policies commonly use exponential backoff with jitter, and the exact schedule depends on the provider. A reasonable internal service may retry after 5 seconds, 30 seconds, 2 minutes, 10 minutes, and 1 hour, while some platforms use a different sequence or continue retries for up to 72 hours. The important design point is that the receiver must assume the maximum delivery window is longer than the normal request timeout. A receiver that retains idempotency records for only 24 hours may be safe for short-lived notifications but unsafe for events that can be replayed during a quarterly audit or a disaster-recovery test.

A second source of duplication is operational rather than technical. Teams sometimes replay an entire event stream, move traffic between staging and production, import historical data, or manually resend failed messages. If those tools do not preserve the original event key, they can create logical duplicates even when every individual HTTP request is unique. A replay tool should therefore accept an explicit mode: preserve original identifiers for exact replay, or generate new identifiers and link them to the original event. Mixing those modes makes it difficult to tell whether a second record is a real new business event or an administrative replay.

## A Reference Architecture for Reliable Processing

The first layer is an HTTP ingress endpoint that authenticates the sender. For a registry SaaS, this could mean verifying a provider signature, checking a timestamp, and rejecting requests outside a five-minute clock-skew window. Signature verification confirms origin and payload integrity; it does not prove that the event is new. The endpoint should also assign a tenant and environment before any business logic runs, because a globally unique event ID may not be unique across separate installations or test tenants.

The second layer is a durable inbox table. A typical row might contain tenant_id, event_key, payload_hash, received_at, status, attempt_count, processed_at, and result_reference. The database should enforce uniqueness on the tenant and event key. The payload hash gives operators a way to detect key reuse with changed content, while attempt_count and timestamps help distinguish one accepted delivery from several retries. A common operational threshold is to retain accepted event keys for at least 90 days, although regulatory, contractual, and audit requirements can justify 1 to 7 years for selected record types.

The third layer is a transactional outbox or equivalent commit boundary. When a filing status changes, the service should update the filing and write an outbox record in the same database transaction. A separate dispatcher then delivers that outbox event to subscribers. This pattern prevents a successful local database change from being lost because a webhook was unavailable, and it also makes delivery reproducible. The subscriber’s inbox and the producer’s outbox solve related problems: the outbox ensures that committed business changes eventually produce notifications, while the inbox ensures that repeated notifications do not repeatedly change business state.

Workers should claim inbox rows with a short lease, such as 60 seconds, and renew that lease if a legitimate job can take longer. If a worker crashes, another worker can reclaim the row after the lease expires. Processing should be transactional where possible, and external calls should be either idempotent or protected by their own operation keys. A worker must not mark an event processed before the associated database changes commit. Otherwise, a crash can leave a permanently skipped event that the sender believes was successfully handled.

## Database Choices and Delivery Semantics

Idempotency storage needs durability, atomic uniqueness, and enough retention for the sender’s retry window. A managed PostgreSQL table is often the simplest choice for a B2B registry product because teams already use relational transactions for filings, deadlines, renewals, and document metadata. A unique index on (tenant_id, event_key) prevents concurrent duplicate inserts, and INSERT ... ON CONFLICT DO NOTHING can record the first arrival without forcing the worker to repeat the business operation. A status field allows the same row to represent received, processing, completed, failed, and quarantined states.

NoSQL systems can work too, but the consistency model must match the concurrency requirement. A conditional write with a unique event key may be sufficient for high-volume notification events, while a queue with a uniqueness mechanism can reduce repeated database writes. The tradeoff is operational visibility: an inbox table is easier to inspect during an incident, whereas a short-lived deduplication cache is often unsuitable for financial, filing-status, or renewal events. Redis can accelerate checks, but it should not be the only durable record unless the business has an explicit loss budget and replay procedure.

The receiver should define a response contract for each situation. Return 2xx after durably recording an event for normal acceptance, return 2xx for a verified duplicate only when the original event is already completed, and return a non-2xx response when the event is malformed, unauthorized, or temporarily unable to be stored. A 409 response can help with a key-and-payload conflict, but many senders retry every non-2xx response, so the sender-specific retry behavior must be tested. A 202 response is useful when the endpoint has durably queued the event for asynchronous work, but it is not appropriate if the application merely acknowledges an event that it might later discard.

| Feature | Relational inbox in PostgreSQL | Short-lived cache plus queue |
| --- | --- | --- |
| Duplicate prevention | Strong uniqueness across tenants and event keys | Usually best-effort and dependent on TTL |
| Failure recovery | Durable status, audit trail, and replayable rows | Lost or forgotten when a key expires |
| Operational fit | Filing, renewal, deadline, and billing events | High-volume, low-risk notifications |
| Typical retention | 90 days to 7 years by policy | Minutes to days, often 1–30 days |
| Cost profile | More storage and index writes, predictable queryability | Lower infrastructure cost, higher incident uncertainty |
| Main weakness | Requires transaction and schema discipline | Cannot independently prove historical processing |

## Handling Partial Failure and Replay Scenarios
A receiver must distinguish between a failed attempt and a failed business operation. A transient database outage should leave the event retryable, while a permanent validation error should be quarantined after a defined number of attempts. A common policy is 5 immediate delivery attempts followed by a dead-letter queue, but the number should reflect the value and time sensitivity of the event. Renewal reminders and deadline alerts may need immediate escalation; an analytics notification can wait several hours. A single retry policy for all event types often creates either unnecessary load or missed deadlines.

Replay needs its own control plane. An operator should be able to search by event ID, tenant, object ID, time range, and processing status, then choose whether to replay only failed events or to rerun completed events. Exact replays should preserve the event ID and use the same inbox record, while business re-executions should use a new execution ID linked to the original. This distinction prevents an administrative replay from being mistaken for a second filing event. In a registry product, the replay interface should also show whether the original action changed a deadline, created a document, or generated a customer-facing message.

Compensating actions are a separate concern from idempotency. If a worker sends an email after updating a filing status, a crash before the email acknowledgement can lead to a duplicate email even if the database update was idempotent. The email operation should therefore use a deterministic delivery key or a communication log with its own uniqueness constraint. Similar rules apply to payment capture, document conversion, and webhook forwarding. A system can be idempotent at the registry boundary while still producing duplicate external effects if each effectful integration lacks its own operation key.

The most useful metric is not merely the number of duplicate payloads received. Track duplicate rate by sender, event type, tenant, and retry reason; measure processing latency at the 50th, 95th, and 99th percentiles; and record the percentage of events completed on the first attempt. A duplicate rate of 0.5% may be normal for a provider with aggressive retries, while 8% can indicate a timeout configuration or a stuck worker. Alert when the 95th-percentile age of pending events exceeds 2 minutes for deadline-sensitive categories, or when the dead-letter rate exceeds 1% over a rolling 15-minute window. These are operating thresholds, not universal standards, and should be adjusted to the event’s business impact.

## Common Design Mistakes and Security Trade-offs

The most common mistake is using a timestamp, object ID, or event type as the deduplication key. A filing object can change many times, and two legitimate events may share the same timestamp at second-level precision. A stable sender event ID is preferable, with a tenant prefix when the sender’s identifiers are only locally unique. Another mistake is checking for an event in application code without a database uniqueness constraint; two workers can both observe “not found” and then both process the event. The check and the claim must happen atomically.

Another error is treating a signature as a uniqueness guarantee. A valid signed request can still be a legitimate retry, and an invalid request should not consume the event key because doing so could block a later valid delivery. A third error is storing the key only after the business operation completes. A crash during processing would then allow a retry to execute the operation again. Teams also frequently set deduplication retention equal to the sender’s visible retry period without accounting for manual replay, audit exports, or disaster recovery.

Security and privacy deserve separate treatment. Payload hashes can help detect tampering, but raw webhook payloads may contain personal data, confidential documents, or unpublished invention details. Encrypt them at rest, restrict operator access, define deletion schedules, and avoid putting unnecessary personal data into log messages. For an intellectual-property rights platform, access controls should preserve the evidence trail around a filing event, yet a webhook body should not become a permanent substitute for the authoritative record. The registry database remains the source of truth; the inbox is evidence that a notification arrived and how it was handled.

Rate limiting and backpressure can accidentally undermine reliability. A receiver that rejects requests under load may cause the sender to retry into the same overload condition. Queueing accepted requests can smooth traffic, but a queue without capacity planning only postpones failure. Teams should measure service-level objectives such as 99.9% accepted within 60 seconds, and should set alerts before queue depth reaches the point where a deadline-sensitive event can no longer be processed. Idempotency does not remove the need for capacity planning; it prevents repeated work from consuming capacity unnecessarily.

## When to Act, and What It Costs

A new webhook integration should include idempotency from the first production release when it can mutate filings, deadlines, renewals, documents, billing records, or customer notifications. Waiting until duplicate emails or duplicate filing records appear makes it harder to establish whether the fault lies in the sender, the network, the receiver, or an internal replay. For read-only analytics events, a shorter deduplication window may be acceptable, but the team should still document the loss and replay consequences. As a rule of thumb, design for at least 7 days of ordinary retries and 90 days of operational replay for business-critical registry events.

The implementation cost depends mainly on existing infrastructure. A modest PostgreSQL inbox, an outbox table, a worker queue, and monitoring can be built with existing cloud services; the direct cost may be a few hundred dollars per month for low-volume tenants, while high-volume deployments can reach several thousand dollars as storage, compute, logs, and observability grow. Managed queue and database products reduce engineering time but add per-message and storage charges. Vendors that sell “exactly once” delivery are usually selling either a stronger infrastructure guarantee or a terminology choice; application teams should still test crash recovery and replay behavior.

The cost of not designing for idempotency is harder to price but often exceeds the engineering cost. A duplicate renewal action can produce duplicate invoices, missed deadline alerts can harm a client’s rights position, and duplicate KYC or identity-verification submissions can create review work and compliance questions. Even an apparently harmless duplicate email can reduce trust in a registry notification. A good rollout should therefore include load tests with 2 concurrent deliveries of every event, a forced worker crash after the business commit, a 60-second network timeout, and a replay of 1,000 historical events. Passing those tests is stronger evidence than a claim that the provider guarantees exactly once delivery.

## A Practical Rollout Standard for Registry Teams

A defensible standard is to assign one immutable event ID at the point where a business change commits, store that ID in an outbox record, and require every subscriber to persist it in a durable inbox before acknowledging acceptance. The producer should preserve the ID across retries and replays. The subscriber should use a unique constraint, process the event once, and return success only after the inbox state and intended local changes are durable. A duplicate with the same key and payload hash can be acknowledged as complete; a duplicate with the same key and a different hash should be quarantined.

The standard should also define ownership. The producer owns delivery attempts and outbox retention. The subscriber owns authentication, validation, idempotency, business processing, and dead-letter handling. Platform operations owns dashboards and replay tools, while security owns access to raw payloads. For an IP registry SaaS, tenant isolation must appear in all three layers: a valid event for one tenant must not update another tenant’s filing, even if object IDs happen to match.

Before launch, measure the sender’s retry schedule, the receiver’s acknowledgement timeout, and the maximum queue delay. Test at least 10,000 events, 2 parallel deliveries per event, and one database failover during processing. The acceptance criteria should include zero duplicate business mutations, 100% of conflicts recorded, a 95th-percentile processing time below the product’s stated objective, and a documented recovery time for the dead-letter queue. If the provider retries for 72 hours, retain keys for at least that period plus an operational margin. This approach is not dramatic or exotic; it is ordinary engineering discipline for a system where legal deadlines and customer records must remain trustworthy.

## Quick answers

### Does Stripe guarantee that a webhook will be delivered exactly once?

No. Stripe documentation describes webhook delivery as a mechanism that can involve retries, so applications should design for duplicate delivery and event processing that can be repeated safely. A receiver should persist the event identifier and use a unique constraint or equivalent durable deduplication mechanism.

### How long should webhook idempotency records be retained?

Retention should exceed the sender’s retry window and the organization’s replay and audit requirements. For ordinary business events, 90 days is a practical starting point, but filing, renewal, billing, or compliance records may require 1 to 7 years depending on contractual and regulatory obligations.

### Is a Redis deduplication key enough for a registry SaaS?

Redis can be useful for a fast preliminary check, but it is usually a weak sole record for legal, billing, or filing-status events. A durable database or queue-backed inbox provides better recovery, auditability, and protection against accidental key expiration.

### What is the difference between idempotency and exactly-once delivery?

Idempotency means repeating the same operation has the same intended effect as executing it once. Exactly-once delivery is a stronger end-to-end claim involving the sender, network, receiver, database, and every external side effect; most webhook architectures should assume at-least-once delivery and engineer the receiver accordingly.

### How should a receiver handle the same event ID with a different payload?

It should not silently treat the request as a normal duplicate. The receiver should compare a payload hash, quarantine the conflict, preserve both request metadata, and notify the responsible team, because key reuse may indicate a sender bug, replay corruption, or unauthorized activity.

Canonical: https://iprs.cloud/knowledge/how_should_you_design_webhook_idempotency_for_reliable_ip_registry_events.php
Markdown: https://iprs.cloud/knowledge/how_should_you_design_webhook_idempotency_for_reliable_ip_registry_events.php/index.md
