Architecture
How HookSniff works under the hood โ system components, data flow, and technology choices.
System Overview
HookSniff consists of four main components:
โโโโโโโโโโโโโโโโโโโ
โ Internet โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโโโโโโโโผโโโโโโโโโ
โ TLS Proxy โ
โ (Fly.io) โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโ
โ โ โ
โโโโโโโโโโผโโโโโโโโ โโโโโโโผโโโโโโ โโโโโโโโโผโโโโโโโโ
โ API Server โ โ Dashboard โ โ Healthcheck โ
โ (Axum/Rust) โ โ (Next.js) โ โ (internal) โ
โโโโฌโโโฌโโโฌโโโโโโโโ โโโโโโโฌโโโโโโ โโโโโโโโโโโโโโโโโ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโผโโโโโบ PostgreSQL (Neon)
โ โ โ
โโโโผโโโโโโโโโโโโโโโโโโโผโโโโโบ Redis
โ โ
โโโโโโโโโโโโโโโโโโโโผโโโโโบ PostgreSQL Queue
โ
โผ
โโโโโโโโโโโโโ
โ Worker โ
โ (Rust) โ
โโโโโโโฌโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ HTTP โ โ gRPC โ โ SQS โ
โ Delivery โ โ Delivery โ โ Delivery โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโComponents
API Server
Async REST API built with Axum (Rust). Handles authentication, webhook ingestion, rate limiting, and idempotency.
- โข PostgreSQL via SQLx (Neon in production)
- โข PostgreSQL-based queue (
webhook_queuetable) - โข API keys (
hr_live_*) + JWT auth - โข SSRF protection, payload validation
- โข Prometheus metrics at
/metrics
Worker
Webhook delivery engine built with Rust + Tokio. Polls the queue and executes deliveries.
- โข HTTP, gRPC, SQS, WebSocket delivery backends
- โข HMAC-SHA256 payload signing (Standard Webhooks)
- โข Fanout: one event โ multiple endpoints
- โข Exponential backoff retry with jitter
- โข Retry scheduler: polls DB every 30s
docs.dashboard
Web UI built with Next.js 14 (App Router), Tailwind CSS, Radix UI, and Tremor.
- โข Endpoint management and monitoring
- โข Delivery logs with search and filtering
- โข Analytics and charts
- โข API key management and billing
Database & Queue
PostgreSQL (Neon) serves as both the primary database and message queue.
- โข Customers, endpoints, deliveries, attempts
- โข
webhook_queuetable for async delivery - โข SSL required (
sslmode=require)
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| API | Rust, Axum, SQLx | Async REST API |
| Worker | Rust, Tokio | Webhook delivery engine |
| docs.dashboard | Next.js 14, Tailwind CSS | Web UI |
| Database | PostgreSQL (Neon) | Persistent storage |
| Queue | PostgreSQL | Async message delivery |
| Auth | JWT + Argon2 + HMAC | Multi-layer auth |
| Billing | Stripe | Payments |
| Deploy | Fly.io | Production hosting |
Data Flow
1. Webhook Ingestion
When you send a webhook via POST /v1/webhooks:
- 1. Authenticate (API key โ customer lookup)
- 2. Check idempotency key (return cached response if duplicate)
- 3. Validate event type format and JSON payload depth
- 4. Check payload size (โค 1 MB) and rate limits
- 5. Verify endpoint exists, is active, matches event filter
- 6. Insert into
deliveriestable (status: pending) - 7. Insert into
webhook_queuefor async processing - 8. Return 200 with delivery ID
2. Webhook Delivery
The Worker polls the queue and delivers webhooks:
- 1. Poll
webhook_queuefor pending deliveries - 2. Look up endpoint URL + signing secret
- 3. Build HTTP request with Standard Webhooks headers
- 4. Send with 30s timeout
- 5. On 2xx: mark as delivered, record attempt
- 6. On failure: record attempt, schedule retry or mark as failed