qhook
The missing layer between webhooks and your app. One binary. Verify, queue, deliver — nothing is lost.
Stripe sends a webhook. Your server is deploying. The event is gone.
qhook sits between webhook providers and your app. It verifies signatures, persists every event before responding, and delivers to your handlers with retry and dead-letter queues. Your webhook source gets a 200 in under 500ms. Your app processes events when it's ready.
Provider → qhook (verify → queue → ACK) → your handler
↓ ↑ retry
persist circuit breaker
Quick Start
# qhook.yaml
database:
driver: sqlite
sources:
stripe:
type: webhook
verify: stripe
secret: ${STRIPE_WEBHOOK_SECRET}
handlers:
billing:
source: stripe
events:
url: http://localhost:3000/webhook
retry:
# → Listening on :8888
# Point Stripe webhook URL to http://yourhost:8888/webhooks/stripe
That's it. Stripe webhooks are verified, queued, and delivered with retry. If your handler is down, events wait in the queue and are retried with exponential backoff.
Why qhook?
Lightweight. A single 16 MB binary. No Redis, no RabbitMQ, no external message broker. SQLite for development, Postgres or MySQL for production.
Dev to prod, same tool. Start with SQLite locally. Deploy to Cloudflare with D1, or scale with Postgres. One line change. Same config, same binary, same behavior.
# Local dev # Cloudflare # Scale
database: database: database:
driver: sqlite driver: d1 driver: postgres
database_id: ... url: ${DATABASE_URL}
Estimated throughput (based on DB write characteristics — run your own benchmarks with scripts/bench-cloudflare.sh or tests/bench.sh for actual numbers):
| Driver | Est. throughput | Best for |
|---|---|---|
| SQLite | ~1K events/sec | Local dev, single instance |
| D1 | ~500 events/sec | Cloudflare deploy, low-medium traffic |
| Postgres | ~10K+ events/sec | Production, multi-instance |
13 webhook providers verified. Stripe, GitHub, Shopify, Twilio, Paddle, PagerDuty, Grafana, Terraform Cloud, GitLab, Linear, Standard Webhooks, HMAC, AWS SNS. IP allowlisting per source.
At-least-once delivery. Events and jobs are persisted in a single transaction before ACK. If qhook crashes, the webhook source retries and nothing is lost.
Production ready. Prometheus metrics, health checks (/health), Slack/Discord alerts, rate limiting (GCRA), circuit breaker, graceful shutdown, OpenTelemetry tracing.
Going Further
qhook does more than receive and forward. Explore when you need it:
| Need | Feature | Guide |
|---|---|---|
| Fan out one event to multiple handlers | Multi-handler routing | Configuration |
| Consumer pulls events instead of push | Pull-mode queues | Pull-Mode Queues |
| Webhook → build → deploy → rollback | Workflow engine | Workflows |
| Send webhooks to your customers | Outbound webhooks | Getting Started |
| Filter events by payload content | JSONPath filtering | Filtering |
| Scale to millions of events/month | Postgres + multi-instance | Scaling Guide |
CLI
All CLI commands | Remote mode for managing deployed instances
Installation
Documentation
totte-dev.github.io/qhook — Getting started, configuration, deployment guides, and more.
Development
This project is developed by a solo engineer with AI pair programming (Claude Code). All code is reviewed, tested (400+ tests), and the architecture decisions are human-driven. AI accelerates implementation; design and quality ownership remain with the maintainer.
Skeptical? The entire codebase is open — read it yourself or let an AI review it for you.
License
Apache-2.0. See LICENSE.