Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

webhook-retries-demo

A deliberately unreliable webhook receiver plus a few scripts that drive Svix through every failure mode you would otherwise have to handle yourself: outages, 429s with Retry-After, timeouts, dead endpoints, signature verification, and replay.

Companion to the DevOps Daily article Stop Building Webhook Retries Yourself.

What is in here

  • receiver/server.js: a Node HTTP server with one path per failure mode. Every request is recorded and exposed at GET /attempts.
    • /ok accepts everything, and deduplicates on svix-id: a redelivered message is acknowledged but not processed twice
    • /flaky returns 500 for the first two attempts of each message, then 200
    • /ratelimited returns 429 with Retry-After: 60 on the first attempt, then 200
    • /slow holds the first attempt open for two minutes (past the sender's timeout), then answers normally
    • /dead always returns 503
    • every path verifies the svix-signature header with the endpoint's secret and answers 401 on a bad signature
  • sender/setup.js: creates the Svix application and one endpoint per path, prints the endpoint secrets
  • sender/send.js: sends one message with a unique eventId and an idempotencyKey (reusing the same eventId is rejected by Svix; reusing the key returns the original message)
  • sender/report.js: lists every delivery attempt Svix made, per endpoint, with status and timing
  • sender/replay.js: resends one message to one endpoint, or recovers every failed message for an endpoint since a timestamp

Run it

You need a Svix API key (free tier is fine) and a public HTTPS URL for the receiver. Svix refuses plain-HTTP endpoint URLs, so the easiest path on a fresh VM is Caddy with automatic TLS on an sslip.io hostname (203-0-113-10.sslip.io resolves to 203.0.113.10).

npm install

# 1. create the app and endpoints (prints ENDPOINT_SECRETS for step 2)
SVIX_API_KEY=... PUBLIC_URL=https://203-0-113-10.sslip.io npm run setup

# 2. start the receiver (behind Caddy or any TLS terminator on :443 -> :8080)
ENDPOINT_SECRETS='{"/ok":"whsec_...","/flaky":"whsec_...",...}' npm run receiver

# 3. send a message; every endpoint receives it
SVIX_API_KEY=... npm run send

# 4. watch the retries land over the next half hour
SVIX_API_KEY=... npm run report -- msg_xxx
curl -s https://203-0-113-10.sslip.io/attempts

# 5. replay
SVIX_API_KEY=... node sender/replay.js resend /dead msg_xxx
SVIX_API_KEY=... node sender/replay.js recover /dead 2026-09-01T18:00:00Z

A Caddyfile for the TLS front is two lines:

203-0-113-10.sslip.io {
  reverse_proxy receiver:8080
}

What you will see

Recorded output from a real run is in RESULTS.md.

MIT licensed.

About

A deliberately unreliable webhook receiver plus scripts that drive Svix through failures, retries, 429s, timeouts, signatures, and replay

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages