A solo hackathon project called Doorbell addresses the fact that GitHub never retries failed webhook deliveries, and most other providers only retry a handful of times before giving up (Shopify even deletes the subscription). Doorbell is a development tunnel that stores incoming webhook requests in Postgres when nobody is connected, returning 202 instead of letting the sender see a 502, then replays them in order once the developer reconnects. The build details cover a Go-based multiplexed tunnel using yamux, a database-enforced single-claim mechanism to avoid duplicate delivery, a security bug where one token accidentally gated both tunnel access and dashboard read access, and infrastructure constraints (raw TCP ports, IPv6-only public gateway, no serverless support) discovered while deploying on Zerops. Known limitations include stripped webhook signatures on replay and untested custom domain support.
Table of contents
The part nobody tells you about tunnelsYou can break it right nowBefore you get excited: is this for you?What 202 actually meansThe whole thing rests on one functionThe bug I shipped, and how I found itWhy this can't run on most of the internetWhat still doesn't workThings you're about to askTry itQuestions this post answers
Does GitHub automatically retry a webhook delivery if my endpoint is down?
No, GitHub does not automatically redeliver failed webhook deliveries. According to GitHub's own documentation, a single failed delivery is left as-is unless you manually redeliver it through the GitHub UI, unlike Stripe, which retries three times in test mode, or Shopify, which retries eight times over four hours before deleting the webhook subscription entirely. Developers wiring up GitHub webhooks can find implementation write-ups like this one on daily.dev.
Why does my ngrok tunnel miss webhook events that arrive while my laptop is disconnected?
A tunnel is a pipe, not a mailbox: if nothing is listening on your end when a request arrives, it has nowhere to go and is lost, not queued. Ngrok's replay feature only works for requests it already saw while you were connected, so events that arrive during a disconnect (lid closed, wifi drop, laptop asleep) are gone unless something durable sits in the path to store them. Anyone debugging flaky local webhook testing can compare tunnel architectures like this on daily.dev.
How can I prevent duplicate webhook delivery when multiple processes try to drain the same queued request?
Claiming a queued request and marking it as taken must happen in a single SQL statement so only one drain process can ever win a given row, preventing two simultaneous reconnects from both delivering the same webhook. This was verified with a test that runs eight concurrent claimers against one row and asserts exactly one wins, since every extra winner represents a webhook delivered twice. Engineers designing exactly-once delivery guarantees can dig into concurrency patterns like this via daily.dev.
2K Impressions1 Comment