Retries & Delivery
Exponential back-off schedule, dead-lettering, auto-disable thresholds, and how to replay.
MemberPass treats webhook delivery as at-least-once. If your endpoint is unreachable or responds non-2xx, the worker retries on the schedule below.
Retry schedule
Every delivery gets up to 8 attempts. The back-off between them is exponential:
| Attempt | Wait before retry |
|---|---|
| 1 | — (immediate) |
| 2 | 10 seconds |
| 3 | 30 seconds |
| 4 | 2 minutes |
| 5 | 10 minutes |
| 6 | 1 hour |
| 7 | 6 hours |
| 8 | 24 hours |
| (after 8) | 72 hours before dead-letter |
Cumulatively, an endpoint has ~4 days of retries before MemberPass gives up. That should cover every reasonable outage short of a permanent DNS change.
Dead-lettering
After the 8th failure, the delivery row is marked dead and the worker stops retrying automatically. Dead rows stay in the database so creators can inspect them in Settings → Webhooks → Deliveries and either retry manually or pull the payload out for debugging.
The POST /v1/webhook-deliveries/{id}/retry endpoint (and the equivalent "Retry" button in the dashboard) re-enqueues a dead row as pending, resetting attempts to 0.
Auto-disable on sustained failure
If an endpoint hits 20 consecutive failures (across many events, not just 20 retries of one), MemberPass flips it to is_active=false automatically and sets disabled_at. This stops us from hammering a permanently broken URL.
When the endpoint owner re-enables it (in the dashboard or via POST /v1/webhook-endpoints/{id} with { "is_active": true }), consecutive_failures resets and fresh deliveries resume.
Response-time budget
Your handler has 10 seconds per delivery. Anything longer counts as a failure and triggers the next retry. If the work itself takes longer, the canonical pattern is:
- Verify the signature.
- Enqueue your own background job with the payload.
- Respond
200 OKimmediately.
This is what we do internally on every job-dispatching endpoint — the webhook worker gets its quick 200 and your heavy processing happens on your own schedule.
What counts as a failure
- Any non-2xx HTTP status.
- Connection timeouts (default: 10 seconds).
- TLS handshake failures.
- DNS resolution failures.
5xx counts and retries. 4xx counts and retries too — even though 4xx usually indicates your code rejected the payload, we still retry because signature verification can be brittle during secret rotation and auto-recovery usually works. If you deliberately want to nack an event, respond 200 and drop it on your side.
Replaying bulk dead deliveries
The Settings → Webhook Deliveries page has a "Replay dead (last 24h)" button that re-queues every dead row whose dead_lettered_at is within the last 24 hours. Use it after you've deployed a fix.
Programmatic equivalent:
curl -X POST https://api.memberpass.net/v1/webhook-deliveries/replay-dead \
-H "Authorization: Bearer $MP_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"since_hours": 24}'Related
How is this guide?