STRIPE WEBHOOKS
Stripe webhook timeouts — slow handlers look like dead endpoints
Stripe expects a fast 2xx response. Handlers that process synchronously — emailing, provisioning, syncing inventory — time out, get marked as failed deliveries, and push the endpoint toward auto-disable.
Why Stripe webhooks fail silently
Synchronous processing in the handler
Doing the real work (provisioning, notifications, DB writes) before responding means every slow job is a delivery failure.
Timeouts count as failures
A timed-out delivery is retried — but repeated timeouts accumulate toward Stripe disabling the endpoint, the same as hard 500s.
Retries amplify the load
Failed deliveries retry for up to ~3 days. A handler that’s slow under load gets slower as retries pile on — a death spiral.
The fix
- 1
Acknowledge first, process later
Verify the signature, persist the event, return 200 — then hand the work to a queue (SQS, BullMQ, a DB job table). This is the canonical webhook pattern.
- 2
Instrument handler latency
Time from receipt to response should be well under a second. If p95 creeps up, you’re one traffic spike from timeouts.
- 3
Idempotency for retries
Store the event id (evt_…) and skip already-processed ones — retries and replays won’t double-charge or double-provision.
- 4
Let the proxy measure for you
HookShield records every forward’s latency and status — p95 is on the dashboard, and timeouts surface as distinct events instead of vanished deliveries.
DEAD-MAN'S SWITCH
Never find out about a dead webhook from a customer again
Point Stripe at a HookShield ingest URL. Every delivery is logged, signed, and forwarded — and if pings stop arriving, you're alerted before the silence becomes an incident.