How to Retry Failed Webhooks: Backoff Strategies and Dead Letter Queues
Webhook delivery fails. Networks have hiccups, services go down, deployments cause brief outages. A proper retry strategy means these are temporary blips, not lost events. Here's how to build one.
Jason Warner
March 19, 2026
How to Retry Failed Webhooks: Backoff Strategies and Dead Letter Queues
Webhook delivery failure is inevitable. Your destination endpoint will occasionally be slow, return a 500, or go down entirely. The question isn't whether delivery will fail — it's whether your infrastructure treats that failure as permanent or temporary.
A proper retry implementation means a momentary outage doesn't lose events. Here's how to build one.
Why You Need Retry Logic
Most webhook sources (Stripe, GitHub, Shopify) have their own retry behavior — they'll retry your endpoint for up to 72 hours. But that's retry from the source to your ingestion layer.
You also need retry from your ingestion layer to your downstream services. If your ingestion endpoint accepts a webhook from Stripe successfully (returns 200) but then fails to deliver it to your internal billing service, Stripe won't retry — it thinks delivery succeeded. That event is silently lost.
This is why retry logic in the delivery layer matters.
Backoff Strategies
No retry (fire and forget). Not recommended for production. Use this only when delivery failure is genuinely acceptable.
Linear backoff. Retry at fixed intervals: every 30 seconds, every 30 seconds, every 30 seconds. Simple but can cause thundering herd problems if many events fail simultaneously.
Exponential backoff. The interval doubles with each retry. Much better for production — it naturally reduces load on a struggling destination and gives it time to recover.
Attempt 1: t=0
Attempt 2: t=30s
Attempt 3: t=1m
Attempt 4: t=2m
Attempt 5: t=4m
Attempt 6: t=8m
Exponential backoff with jitter. Add a random offset to each retry interval to prevent synchronized retry storms when many events fail at the same time. This is the recommended production approach.
Retry Count: How Many Is Right?
- Critical events (payments, order fulfillment): 10-20 retries, exponential backoff, up to 24-48 hours of retry window
- Non-critical events (activity logs, notifications): 3-5 retries, exponential backoff, 1-2 hour window
Dead Letter Queues
When a delivery exhausts all retries, it shouldn't disappear. It should go to a dead letter queue — a separate store for events that couldn't be delivered.
The dead letter queue lets you:
- Audit what was lost and why (inspect the last response code and body)
- Fix the underlying problem (repair the destination endpoint, fix a bug)
- Reprocess the event once the problem is fixed
Without a dead letter queue, exhausted retries silently vanish. With one, they're inspectable and recoverable.
Event Replay
Beyond dead letters, you also want the ability to replay arbitrary historical events:
- You had a bug in your handler for 6 hours — replay all events from that window
- A new integration was added mid-stream — replay the last N days of events against it
- Testing a code change with production event shapes
Setting Up Retry in Bluejay Relay
- Open an Integration and click into a Destination
- Under Retry Policy, select Exponential
- Set Max Retries (3-10 for most use cases)
- Set Multiplier (1.5-2.0 is typical)
- Set Max Delay to cap the maximum interval
Failed deliveries are automatically retried on schedule. Exhausted retries land in the Dead Letter Queue at /dead-letters. Select any event in the log and click Replay to manually resend, with bulk and time-travel options available.
Start free on Bluejay Relay — the dead letter queue is included on every tier; configurable retries and event replay come with the paid plans.
Make your webhooks bulletproof.
Automatic retries with backoff, a dead-letter queue, and full replay — so a failed delivery is recoverable, not lost. Free to start.