Skip to content

Why Sparrow

Sparrow is a self-hosted webhook delivery platform built for teams that want full control over their webhook infrastructure. No per-message pricing, no vendor lock-in, no external dependencies beyond PostgreSQL.

Sparrow is MIT-licensed, and all core features are available in the open-source codebase (including envelope encryption, webhook signing, retries, and health tracking).

Production-Grade Delivery

At-least-once delivery with exponential backoff, 10-category error classification, per-webhook health tracking (healthy/degraded/unhealthy state machine), and automatic retry logic that distinguishes retryable failures from permanent ones.

Cryptographic Signing

Every delivery is signed in the Standard Webhooks format — HMAC-SHA256 by default, or Ed25519 per webhook for public-key verification. Ed25519 keypairs are generated automatically on opt-in.

Encryption at Rest

Webhook secrets, signing keys, and sensitive headers are envelope-encrypted with AES-256-GCM and per-record data encryption keys. Not just “encrypted in the database” — actual envelope encryption with key hierarchy.

Zero External Dependencies

PostgreSQL is the only infrastructure requirement. No Redis, no message broker, no object storage. The River job queue runs inside PostgreSQL. One database to back up, monitor, and scale.

Consumer Self-Service Portal

Hand each consumer a scoped, expiring link to a portal where they register their own endpoints, manage subscriptions, and inspect and retry their own deliveries — no admin API key, no visibility into anyone else’s data. One admin call mints the token; it is stateless (HMAC-signed, revoked by expiry) and rides in the URL fragment. This is the App Portal capability Svix is known for — built in, no extra service to run.

The table below compares Sparrow with the main alternatives for webhook delivery: Svix (open-source + cloud), Convoy (source-available, Elastic 2.0), Hookdeck (SaaS platform with open-source Outpost agent), AWS SNS (managed), and building it yourself (DIY).

CapabilitySparrowSvixConvoyHookdeckAWS SNSDIY
Fully open source (MIT)YesPartial (OSS core, paid features)No (Elastic 2.0, source-available)Partial (Outpost OSS, core platform closed)NoYes
Self-hostedYesYesYesPartial (Outpost self-hosted, platform SaaS)No (Managed)Yes
No vendor per-message pricing (self-hosted)Yes (self-hosted; infra only)NoYes (self-hosted)NoNoYes (your infra only)
Infra complexity (core deps)PostgreSQL onlyPostgreSQL (+ Redis for HA)PostgreSQL + RedisSaaSManagedVaries
Job queue backendPostgreSQL (River)Redis-backed queue/workersBackground workers + RedisManagedManagedVaries
Webhook signingDual HMAC-SHA256 + Ed25519HMAC-SHA256HMAC-SHA256HMAC-SHA256X.509 signature (not HMAC)Manual
Security model for secretsEnvelope encryption with per-record DEKsEncrypted at rest (service-managed keys)Deployment-dependent (no built-in envelope hierarchy)Vendor-managed encryptionVendor-managed encryptionManual
Payload transformationGo templates per subscription (37 functions, incl. structural + arithmetic)Varies by edition/planYes (JS transform)Yes (JS transform)NoManual
Per-webhook rate limitingLeaky bucket (DB-backed)Available (details vary)YesYesRegional quotasManual
Delivery semanticsAt-least-once + explicit idempotency modelAt-least-once + retriesAt-least-once + retriesAt-least-once + replayAt-least-onceVaries
Delivery health modelState machine (healthy/degraded/unhealthy)Endpoint statusCircuit breakerDashboard metricsCloudWatchManual
Error classification10 protocol-aware categories with retryability flagsBasic status and error reportingSuccess/failureCategorizedCloudWatchManual
Bulk retry/re-pushDeterministic snapshot-based (up to 10K)Not in OSSManual retryUI retryNoManual
Idempotent ingestionBuilt-in dedup with idempotency keysApplication-level (no OSS ingest dedup)Event IDsDedup availableMessage dedup (5min)Manual
REST / OpenAPI APIYes (OpenAPI 3.1 spec)Yes (REST)Yes (REST)Yes (REST)NoManual
Event schema validationSoft validation (warns, never rejects; server-side check on test pushes)JSON Schema defs (not enforced)NoFilters (not schema)NoManual
Prebuilt integration recipesYes (Slack, Discord, PagerDuty, ntfy, ClickHouse, Twilio, SendGrid — one YAML, rendered server-side)LimitedLimitedYes (integrations)Limited destinationsManual
Inbound ingestion (verify provider signatures)Yes (sparrow-sources: Stripe, GitHub, cron schedules)Yes (Ingest product)Yes (incoming webhooks)Yes (core feature)NoManual
Non-HTTP delivery (email, object storage, OTLP)Yes (sparrow-sinks: SMTP, S3/MinIO, OTLP logs)LimitedLimitedLimitedSNS-native targetsManual
Self-monitoring alertsBuilt-in system events (webhook health, delivery failure) + opt-in email alertsOperational webhooksAlert configsIssue alertsCloudWatch alarmsManual
CLI toolingYes (push, tail, local listen, apply recipes, debug templates)YesYesYes (localhost tunnels)AWS CLIManual
Web dashboardEmbedded SvelteKitIncludedIncludedIncludedConsoleNo
Tracing & metricsOpenTelemetry (traces + metrics + logs, job-level propagation)LoggingPrometheus metricsDashboardCloudWatchManual
SSRF protectionBuilt-in (private IPs, redirects)Built-in controls (plus proxy best practices)Built-in controls / IP filteringManagedN/AManual
Client SDKs3 (Go, Python, TypeScript)Broad coverageMultipleMultipleAll AWS SDKs0
Consumer app portalYes (embeddable, token-scoped)Yes (embeddable)Yes (Portal Links)Yes (Outpost/managed)NoNo
Multi-region / HA storyPostgreSQL-native HA + stateless workersVendor/infra-managedVendor/infra-managedVendor-managedGlobal managed serviceManual
Multi-tenant SaaS modeNo (single-tenant focus)YesYesYesYesManual

Since Svix is the closest competitor architecturally, here’s a deeper look:

CapabilitySparrowSvix OSS
Event schema validationSoft validation (warnings, never rejects)JSON Schema defs (not enforced)
Consumer isolationBuilt-in logical separationApplication-level
API protocolREST/HTTP on :8080 (OpenAPI 3.1 spec)REST API only
Deployment shapeSingle binary + Docker imageBroader deployment options
Container imageDistroless (~15MB), non-rootStandard
Consumer self-service portalBuilt-in, token-scoped — embed or hand off a linkApp Portal (magic-link session)
  • Operational simplicity — one database, one binary, no Redis. Fewer moving parts means fewer failure modes in production.
  • Cryptographic depth — Standard Webhooks signing (HMAC-SHA256 or Ed25519) and real envelope encryption are production security features that most webhook platforms skip or gate behind paid tiers.
  • Payload transformation — Go text/template transforms per subscription (37 built-in functions, including structural dict/list/merge/append and arithmetic) let you reshape payloads for different consumers (Slack, PagerDuty, custom formats) without proxy layers. This is a deliberate design choice over an embedded JavaScript runtime: templates are parsed once and cached, so each delivery runs with near-zero overhead; there is no per-worker JS VM to pool, no extra dependency, and the server stays a single distroless ~15MB binary with a small, predictable memory footprint. Parsed templates are concurrency-safe and reused across all delivery workers, so transform throughput scales with workers instead of contending on interpreter instances. Every transform is bounded by a 1MB output cap and a 5s execution timeout. Available to all users, not a paid feature.
  • Error intelligence — 10 error categories with retryability classification. You know why a delivery failed (DNS resolution? TLS handshake? Rate limited? Connection refused?), not just that it failed.
  • Bulk operations — snapshot-based batch re-push and retry with deterministic execution. What you filter is exactly what gets retried — no race conditions from new data arriving between search and action.
  • Observability — full OpenTelemetry integration with trace propagation through the job queue. Trace a single event from ingestion through fan-out to every delivery attempt.
  • Idempotency — built-in deduplication on event ingestion prevents double-processing without application-level workarounds.
  • Rate limiting — per-webhook delivery rate limiting with leaky bucket and HTTP 429 Retry-After parsing, all backed by PostgreSQL (no Redis).
  • No Redis — Sparrow uses PostgreSQL for everything including job queuing (via River). This keeps operational complexity lower for teams that want fewer infrastructure dependencies.
  • Satellites — companion tools built entirely on the public REST API: a CLI (push, tail, local listen, template debugging), recipes (Slack, Discord, PagerDuty, ntfy, ClickHouse as one YAML file each, rendered server-side), sources (Stripe/GitHub signature verification + cron schedules re-published as typed events), and sinks (SMTP email, S3/MinIO archives, OTLP log export). The core stays one small server; delete every satellite and Sparrow still works.
  • Self-monitoring — Sparrow emits its own system events (sparrow.webhook.health_changed, sparrow.webhook.delivery_failed) through the same pipeline it delivers with, and can email you about them via opt-in alert configs — your webhook infrastructure alerts on itself, no external monitoring stack required.
  • Consumer self-service — mint a scoped, expiring token for one consumer and hand them the embedded portal: they register endpoints, manage subscriptions, and inspect and retry their own deliveries with no API key and no visibility into any other consumer. Stateless HMAC tokens (signed with the encryption key, revoked by expiry) mean no session store and no extra service to run — the same end-user portal Svix ships as its App Portal, without the SaaS.
  • Client SDK breadth — Sparrow ships 3 generated SDKs today. Some alternatives provide broader first-party SDK coverage.
  • Multi-tenant SaaS mode — Svix, Convoy, and Hookdeck are designed for SaaS platforms where each customer manages their own webhooks. Sparrow is designed for teams running their own infrastructure.
  • Managed cloud offering — Svix Cloud and Hookdeck handle infrastructure for you. Sparrow is self-hosted only.
  • JavaScript transforms — Convoy and Hookdeck use JavaScript for payload transformation, which may be more familiar to web developers. Sparrow deliberately uses Go templates instead: cached, concurrency-safe execution with no embedded JS runtime means a smaller memory footprint, higher throughput, and zero extra dependencies — the tradeoff is JavaScript’s familiarity. The 37 built-in functions (structural map/list building, arithmetic, dig, type coercion) cover payload reshaping without a scripting engine.
  • Ecosystem maturity — alternatives may offer larger ecosystems and more prebuilt integrations. Sparrow’s recipes cover Slack, Discord, PagerDuty, ntfy, and ClickHouse today; anything else is a Go template away, but not prebuilt.
  • Hookdeck OSS scope — Hookdeck Outpost is open source and can be self-hosted, while Hookdeck’s core platform remains SaaS.
  • Comparison drift — vendor plans and packaging change frequently; verify critical buying decisions against current vendor docs.

Sparrow runs anywhere you can run one container and connect it to PostgreSQL:

  • Docker Compose for local development and small deployments
  • Any container platform — the distroless image is ~15MB with zero OS-level attack surface