Webhook retries
Webhook receivers fail, so the sender must keep each event and retry it. Here 20 percent of attempts fail. Durable storage, bounded retries and a dead-letter record make sure that 0 events disappear.
See it on the board
The same traffic runs on two boards. The simulator measured both when this page was built.
| Measure | Goal | One try, no storage | Durable events, bounded retries |
|---|---|---|---|
| Lost writes | none | 394 Fail | 0 Pass |
| Security score | at least 1 | 0 Fail | 1 Pass |
| Monthly cost | 24 USD/mo | 24 USD/mo | |
| p99 latency | 48 ms | 48 ms | |
| Error rate | 0% | 0% |
Key numbers
| Number | Value |
|---|---|
| Default delivery tries | 5 tries |
| External API call, median | 150 ms |
| Calls per second, one external API | 100 ops/s |
3 retries per call · no jitter · peak 6.0× normal load
How it works
A webhook is a call from your system to a customer's server. You do not control that server. It can be slow, down, or wrong. In the mini board 20 percent of attempts get rejected. If the sender fires each call once and forgets it, one in five events is lost.
A sender that keeps its promise has four parts. It stores each event in a durable queue before it sends anything. It retries a failed call with backoff, so a short outage heals. It limits the tries, so a dead receiver does not take capacity forever. And when the tries run out, it moves the event to a dead-letter record, where the customer or an operator can see it and ask for a replay.
Two more parts make the retries safe. Sign every call, so the receiver can check who sent it and that the body is not changed. And send a stable event ID with each attempt, so a receiver that got the first call can ignore the repeat.
Every event ends in one of two states: delivered, or stored as failed. No event may simply disappear.
In the levels you build the sender, with its queue, retries, signature and dead-letter record, and check that 0 events are lost.