Currently Available: Need a skilled Software Developer for your next project?
Categories
APIs

Understanding Webhook Retry Windows and Event Expiration

When a service sends an event to your webhook endpoint, it sends an HTTP request telling your code that something happened. If your endpoint does not accept the request, the provider may try again. The retry window is the period during which the provider keeps attempting delivery. Event expiration describes what happens when that period ends before delivery succeeds.

Providers set different retry rules, and some do not retry automatically. When a provider closes its retry window, it stops trying to deliver the event; unless the provider or your own infrastructure saved a copy for later recovery, your service will not receive it. Knowing the provider’s rules helps you decide how to capture failures and recover missed updates.

How retry windows work

A provider’s retry policy specifies which failures trigger another attempt and how long the provider waits. It also sets when the provider stops retrying. Some policies limit the number of attempts, others limit elapsed time, and some use both. There is no shared retry schedule across providers.

Providers commonly increase the delay between attempts, a strategy called exponential backoff. Some also add a small random delay, or jitter, so many endpoints do not receive retries at the same moment. The exact schedule matters: a short series of retries over minutes offers less recovery time than attempts spread across days.

For example, Marketplacer’s webhook policy documents a default of 25 retries and a time limit from when the payload was generated. Its documented delays range from one minute to four days. That schedule illustrates why a retry count alone does not tell you how long an event remains deliverable.

Providers also decide which responses count as retryable. Marketplacer, for example, says it does not retry some HTTP 4xx responses (client-error responses), except HTTP 429. Other providers set their own rules. Check the provider’s documentation for the response codes and timeout behavior that apply to your endpoint. A failed attempt that the provider classifies as non-retriable can end delivery before the retry window closes.

What expiration means for a failed event

When a provider exhausts its attempts or reaches its time limit, it stops scheduling delivery. The event has expired when the provider stops trying to deliver it automatically. The term does not, by itself, tell you whether the provider retains diagnostic records or offers a manual resend.

If the provider discards the event and neither side saved a copy, your endpoint cannot recover the original notification from that delivery. The provider's data changes remain in place even though your service missed the notification. Your service may therefore have an outdated view until it gets the information another way.

Providers handle exhausted deliveries differently. A provider may mark an event as failed and allow manual redelivery. GitHub, for example, documents manual redelivery for failed webhook deliveries, which lets someone send a failed delivery again by hand, rather than retrying it automatically. Other providers may move failed events into a dead-letter queue (DLQ), a separate holding area for events that could not be delivered. A DLQ can preserve the payload and failure details so an operator can investigate and replay the event, as described in the Hookdeck and Svix guidance on dead-letter queues.

How to protect events from permanent loss

Start by checking the provider’s current documentation for its retry duration, attempt limit, retryable responses, and recovery options. Confirm whether it offers a failure log, manual redelivery, or a DLQ. GitHub’s failed-delivery documentation, for example, describes its manual redelivery option; a provider that offers no such option requires a recovery plan on your side.

Your endpoint should save each accepted event to durable storage before returning a success response, then process it asynchronously. Durable storage means the event survives a service restart or temporary outage. This shortens the time the provider must wait for acknowledgment and gives your code a local copy to process later. Give each event an identifier that stays the same when the provider retries it, and make the handler idempotent, meaning it can process the same event more than once without applying the change twice. Providers retry after failures, and the same event can arrive again even after an earlier attempt appeared to succeed.

For critical data, compare your local records with the provider’s records on a schedule, then repair any differences. This regular comparison, called reconciliation, catches missed events when retries expire or delivery fails in a way your endpoint does not detect. If you use a DLQ, decide how long it keeps events and review failed events so the queue does not grow indefinitely. Webhook reliability guidance discusses preserving events for inspection and replay.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *