Webhook Retry Logic: A Practical Guide
Reliable webhook delivery requires more than retrying every error. Backoff, idempotency, limits, and visibility must work together.
Webhook retries are simple only when the happy path is the only path considered. In production, the sender must distinguish temporary failures from permanent ones, avoid duplicate side effects, and give operators enough information to recover safely.
Retry temporary failures
Retry network errors, timeouts, HTTP 408, HTTP 429, and most 5xx responses. Do not automatically retry every 4xx response: a malformed payload or invalid authentication will not improve with time.
Use bounded exponential backoff
A practical schedule might be:
1 minute
5 minutes
30 minutes
2 hours
8 hours
24 hours
Add a small random jitter so many failed deliveries do not retry at exactly the same moment. Always cap both the interval and the total number of attempts.
Make the receiver idempotent
Retries create duplicates whenever the sender times out after the receiver has completed the work. Store a stable delivery or event identifier and return success when it has already been processed.
const existing = await db.processedEvents.findUnique({
where: { eventId: request.headers.get("x-event-id") }
})
if (existing) return new Response("ok", { status: 200 })
The idempotency record and business update should be committed atomically where possible.
Sign and timestamp requests
Use an HMAC signature over the raw body and include a timestamp. Reject invalid signatures and timestamps outside a short tolerance window. This protects integrity and reduces replay risk.
Preserve an execution history
Store the attempt number, time, response status, duration, and a bounded response excerpt. Redact secrets and define retention. Operators should be able to answer what was sent, what came back, and what happens next.
Use a dead-letter state, not a black hole
After the final attempt, move the delivery to a visible failed state. Provide alerting and a safe replay action. A dead-letter queue is useful only when somebody owns the recovery process.
Retries are not a reliability feature by themselves. Reliability comes from making duplicate execution safe and failed delivery understandable.
Disclosure · Built by the AllClearStack team
When ownership is the expensive part
Webhook Scheduler handles delayed HTTP delivery, automatic retries, per-attempt logs, and one-call cancellation. Try a real delivery without creating an account.