{"id":46950899,"url":"https://github.com/totte-dev/qhook","last_synced_at":"2026-04-02T17:52:59.669Z","repository":{"id":342919988,"uuid":"1175290404","full_name":"totte-dev/qhook","owner":"totte-dev","description":"Lightweight event gateway with queue and retry. SQS for webhooks and events.","archived":false,"fork":false,"pushed_at":"2026-03-25T21:34:31.000Z","size":786,"stargazers_count":1,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T18:41:56.550Z","etag":null,"topics":["event-driven","event-gateway","poll-based","queue","retry","rust","webhook","webhook-gateway"],"latest_commit_sha":null,"homepage":"https://totte-dev.github.io/qhook/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/totte-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-07T14:04:52.000Z","updated_at":"2026-03-20T00:43:12.000Z","dependencies_parsed_at":"2026-03-14T11:01:52.863Z","dependency_job_id":null,"html_url":"https://github.com/totte-dev/qhook","commit_stats":null,"previous_names":["totte-dev/qhook"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/totte-dev/qhook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totte-dev%2Fqhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totte-dev%2Fqhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totte-dev%2Fqhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totte-dev%2Fqhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/totte-dev","download_url":"https://codeload.github.com/totte-dev/qhook/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totte-dev%2Fqhook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31312744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["event-driven","event-gateway","poll-based","queue","retry","rust","webhook","webhook-gateway"],"created_at":"2026-03-11T08:05:41.943Z","updated_at":"2026-04-02T17:52:59.656Z","avatar_url":"https://github.com/totte-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# qhook\n\n**The missing layer between webhooks and your app.** One binary. Verify, queue, deliver — nothing is lost.\n\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](#license)\n[![Rust](https://img.shields.io/badge/rust-1.85%2B-orange.svg)](https://www.rust-lang.org/)\n[![CI](https://github.com/totte-dev/qhook/actions/workflows/ci.yml/badge.svg)](https://github.com/totte-dev/qhook/actions/workflows/ci.yml)\n\n---\n\nStripe sends a webhook. Your server is deploying. The event is gone.\n\nqhook 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.\n\n```\nProvider → qhook (verify → queue → ACK) → your handler\n              ↓                               ↑ retry\n           persist                         circuit breaker\n```\n\n## Quick Start\n\n```bash\ncargo install qhook\n```\n\n```yaml\n# qhook.yaml\ndatabase:\n  driver: sqlite\n\nsources:\n  stripe:\n    type: webhook\n    verify: stripe\n    secret: ${STRIPE_WEBHOOK_SECRET}\n\nhandlers:\n  billing:\n    source: stripe\n    events: [invoice.paid, customer.subscription.updated]\n    url: http://localhost:3000/webhook\n    retry: { max: 5 }\n```\n\n```bash\nqhook start\n# → Listening on :8888\n# Point Stripe webhook URL to http://yourhost:8888/webhooks/stripe\n```\n\nThat'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.\n\n## Why qhook?\n\n**Lightweight.** A single 16 MB binary. No Redis, no RabbitMQ, no external message broker. SQLite for development, Postgres or MySQL for production.\n\n**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.\n\n```yaml\n# Local dev            # Cloudflare           # Scale\ndatabase:              database:              database:\n  driver: sqlite         driver: d1             driver: postgres\n                         database_id: ...       url: ${DATABASE_URL}\n```\n\nEstimated throughput (based on DB write characteristics — run your own benchmarks with `scripts/bench-cloudflare.sh` or `tests/bench.sh` for actual numbers):\n\n| Driver | Est. throughput | Best for |\n|---|---|---|\n| SQLite | ~1K events/sec | Local dev, single instance |\n| D1 | ~500 events/sec | Cloudflare deploy, low-medium traffic |\n| Postgres | ~10K+ events/sec | Production, multi-instance |\n\n**13 webhook providers verified.** Stripe, GitHub, Shopify, Twilio, Paddle, PagerDuty, Grafana, Terraform Cloud, GitLab, Linear, Standard Webhooks, HMAC, AWS SNS. IP allowlisting per source.\n\n**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.\n\n**Production ready.** Prometheus metrics, health checks (`/health`), Slack/Discord alerts, rate limiting (GCRA), circuit breaker, graceful shutdown, OpenTelemetry tracing.\n\n## Going Further\n\nqhook does more than receive and forward. Explore when you need it:\n\n| Need | Feature | Guide |\n|------|---------|-------|\n| Fan out one event to multiple handlers | Multi-handler routing | [Configuration](https://totte-dev.github.io/qhook/configuration) |\n| Consumer pulls events instead of push | Pull-mode queues | [Pull-Mode Queues](https://totte-dev.github.io/qhook/guides/pull-mode-queues) |\n| Webhook → build → deploy → rollback | Workflow engine | [Workflows](https://totte-dev.github.io/qhook/guides/workflows) |\n| Send webhooks to your customers | Outbound webhooks | [Getting Started](https://totte-dev.github.io/qhook/getting-started) |\n| Filter events by payload content | JSONPath filtering | [Filtering](https://totte-dev.github.io/qhook/guides/filtering) |\n| Scale to millions of events/month | Postgres + multi-instance | [Scaling Guide](https://totte-dev.github.io/qhook/guides/scaling) |\n\n## CLI\n\n```bash\nqhook start                # Start server\nqhook status               # Overview at a glance\nqhook tail                 # Stream events in real time\nqhook inspect \u003cEVENT_ID\u003e   # Full lifecycle of an event\nqhook validate             # Check config before deploy\n```\n\n\u003e [All CLI commands](https://totte-dev.github.io/qhook/cli) | [Remote mode](https://totte-dev.github.io/qhook/cli#remote-mode) for managing deployed instances\n\n## Installation\n\n```bash\ncargo install qhook                    # From crates.io\ndocker pull ghcr.io/totte-dev/qhook    # Docker image (~16 MB)\n```\n\n## Documentation\n\n**[totte-dev.github.io/qhook](https://totte-dev.github.io/qhook/)** — Getting started, configuration, deployment guides, and more.\n\n## Development\n\nThis 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.\n\nSkeptical? The entire codebase is open — read it yourself or let an AI review it for you.\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotte-dev%2Fqhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftotte-dev%2Fqhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotte-dev%2Fqhook/lists"}