Webhook delivery, retries, and replay
Relay Webhook Delivery
A local webhook delivery system with signed requests, a PostgreSQL-backed worker, automatic retries, replay, and a dashboard for delivery history.
- Role
- Independent full-stack project
- Scope
- Local distributed system
- Year
- 2026
What I built
Relay accepts synthetic events, signs each request with HMAC-SHA256, and delivers it to a registered demo endpoint. The system is split into an ASP.NET Core API, a separate .NET worker, a PostgreSQL database, a Next.js dashboard, and a receiver simulator. Docker Compose starts the five services together.
Delivery path
The API validates and stores each event before the worker claims queued deliveries from PostgreSQL. Claims use FOR UPDATE SKIP LOCKED, so several worker instances can take different jobs without processing the same delivery at the same time. The dashboard shows endpoint state, delivery history, attempts, correlation IDs, and errors.
Failure and duplicate handling
Failed requests are retried after one, two, and four seconds, with a maximum of four attempts. Expired worker claims are recovered after a crash. Idempotency keys protect event creation and manual replay from duplicate requests, while replay creates a new delivery linked to the failed original.
Verification
The repository has 26 unit tests, 35 PostgreSQL integration tests, 15 frontend tests, and four Playwright workflows. CI builds all five Compose services and exercises successful delivery, retry exhaustion, replay, endpoint lifecycle, filtering, pagination, and history retention.
The trade-off
Relay waits one second before the first retry, two before the next, and four before the last. The short delays make the full failure path practical to test on a laptop. Relay is still a local demo, not a hosted service.
Relay currently accepts only the demo destinations listed in the repository. It has no authentication, multitenancy, billing, cloud setup, or support for arbitrary URLs. A hosted version would need destination ownership checks and authentication before any scaling work.