Learning lens
Start with judgment, not a universal prescription.
This page is a learning model for understanding the capability. It does not claim exact production internals, exact costs, or an infinite-scale architecture.
Evidence
Conceptual pattern
0->1 default
Start with a durable queue, clear ownership, retries, and idempotency before building a larger event platform.
Cost drivers
Watch for breakpoints
- -backlog grows during normal traffic
- -manual recovery becomes frequent
- -independent consumers need replay
Learn first
Concepts behind this architecture
Pub/Sub
Broadcast events from publishers to many independent subscribers.
Circuit Breaker
Stop calling an unhealthy dependency before failures cascade through the system.
Distributed Tracing
Follow one request across services, queues, databases, and external calls.
Eventual Consistency
Allow replicas to temporarily disagree while guaranteeing they converge later.
The Problem
When events happen in your system (payment completed, order shipped, user signed up), external systems need to know. Webhooks push HTTP POST requests to customer-configured URLs when events occur. The challenge: the internet is unreliable. Customer endpoints go down, respond slowly, or return errors. You must ensure delivery with retries, prevent duplicate processing, secure payloads with signatures, and manage thousands of webhook endpoints with wildly varying reliability — all without letting slow endpoints back up your event pipeline.
Architectural Approaches
Synchronous Dispatch with Retry Queue
Attempt delivery immediately when the event occurs. If the endpoint is down or slow, enqueue the webhook for retry. A background worker processes the retry queue with exponential backoff. Simple and low-latency for healthy endpoints.
Pros
- +Lowest latency for healthy endpoints — near-instant delivery
- +Simple architecture — direct HTTP call + retry queue
- +Easy to reason about delivery order
Cons
- −Slow endpoints block the dispatch thread
- −Must handle timeouts carefully (5-10 second max)
- −Synchronous dispatch can overwhelm the event producer under load
- −Retry queue can grow unbounded if many endpoints are down
Fully Async Queue-Based Dispatch
All webhooks are enqueued immediately, and a fleet of workers processes the queue. Each worker picks a webhook, delivers it, and handles the result (success, retry, or dead-letter). The event producer never blocks on delivery. This is the standard pattern for high-volume webhook systems.
Pros
- +Event producer is completely decoupled from delivery
- +Workers can be scaled independently based on queue depth
- +Natural backpressure — queue absorbs spikes
- +Easy to add rate limiting per endpoint
Cons
- −Added latency from queue processing (1-5 seconds typical)
- −More infrastructure to manage (queue + workers)
- −Must handle queue ordering carefully for per-endpoint FIFO
- −Monitoring and observability are more complex
Managed Webhook Service
Use a managed service like Svix, Hookdeck, or AWS EventBridge to handle webhook delivery. Your system publishes events to the service, and it handles endpoint management, delivery, retries, and monitoring.
Pros
- +Zero infrastructure to manage
- +Built-in retry, monitoring, and endpoint management UI
- +Handles edge cases (endpoint rotation, signature verification)
- +Customer-facing portal for managing webhook subscriptions
Cons
- −Per-event pricing can be expensive at high volume
- −Vendor dependency for a critical integration path
- −Less control over delivery behavior and timing
- −Data passes through a third party
Architecture
Key Components
Webhook Service
Core orchestrator that receives events from the event bus, resolves which endpoints are subscribed to each event type, generates signed payloads, and enqueues delivery jobs. Handles event filtering (only send “order.completed” events to endpoints subscribed to order events).
Signature Generator
Signs each webhook payload with HMAC-SHA256 using a per-endpoint secret key. The signature is sent in a header (e.g., X-Webhook-Signature). Customers verify the signature to ensure the webhook came from your system and wasn’t tampered with.
Dispatch Workers
Pool of HTTP client workers that deliver webhooks. Each worker sends a POST request with the signed payload, enforces a timeout (5-10 seconds), and records the result. Handles connection pooling, TLS verification, and redirect following (with limits).
Retry Scheduler
Manages failed deliveries with exponential backoff: 1min, 5min, 30min, 2hr, 8hr, 24hr. Tracks attempt count per event. After max attempts (typically 5-8 over 24-72 hours), moves to the dead-letter queue and optionally notifies the endpoint owner.
Endpoint Manager
CRUD API for customers to register, update, and delete webhook endpoints. Stores the URL, subscribed event types, signing secret, and active/paused status. Supports endpoint verification (send a challenge and expect a specific response).
Delivery Dashboard
Customer-facing UI showing delivery history: timestamp, event type, response status code, response time, and payload. Allows customers to inspect failed deliveries, view request/response headers, and manually retry failed events.
Data Model
HMAC Signature Verification
Webhook payloads must be verified by the receiver to ensure authenticity and integrity.
Signing process (your side):
- Generate a unique secret per endpoint (32+ random bytes, base64 encoded)
- For each delivery, compute:
signature = HMAC-SHA256(secret, timestamp + "." + payload_body) - Send headers:
X-Webhook-Signature: t=1707100000,v1=abc123...andX-Webhook-Timestamp: 1707100000
Verification process (customer side):
- Extract the timestamp and signature from the header
- Reject if timestamp is older than 5 minutes (replay protection)
- Compute expected signature:
HMAC-SHA256(secret, timestamp + "." + raw_body) - Compare with constant-time comparison to prevent timing attacks
- If match, process the webhook; if not, return 401
Including the timestamp in the signature prevents replay attacks — an attacker can’t re-send a captured webhook because the timestamp check will fail.
Secret rotation: Support multiple active secrets per endpoint. When rotating, sign with the new secret and include signatures for both old and new secrets in the header. Customers verify against both during the rotation window.
Retry Strategy and Circuit Breaking
Not all failures are equal. The retry strategy should adapt to the failure type.
Retryable failures:
- Network timeout → retry with exponential backoff
- 5xx server error → retry (server is temporarily down)
- Connection refused → retry (server restarting)
Non-retryable failures:
- 4xx client error (except 429) → don’t retry, the endpoint is misconfigured
- Invalid URL → don’t retry, notify the customer
- TLS certificate error → don’t retry, security issue
- 429 Too Many Requests → retry, but respect the Retry-After header
Retry schedule: 1min → 5min → 30min → 2hr → 8hr → 24hr (6 attempts over ~34 hours). After final failure, move to DLQ.
Circuit breaker per endpoint: If an endpoint fails 10 consecutive deliveries, “open” the circuit — pause all deliveries to that endpoint. Periodically send a “health check” delivery. If it succeeds, close the circuit and resume. This prevents wasting resources on consistently failing endpoints.
Auto-disable: After 72 hours of continuous failures, automatically disable the endpoint and notify the customer via email. Require them to re-enable manually after fixing the issue.
Ordering and Idempotency
Delivery ordering: Webhooks may arrive out of order due to retries and parallel dispatch. If order matters (e.g., order.created must arrive before order.shipped), options:
- Include a sequence number in the payload. Receivers buffer and reorder.
- Use per-endpoint FIFO queues (SQS FIFO, or single-worker-per-endpoint). Slower but ordered.
- Accept out-of-order delivery and include enough state in each event for the receiver to reconcile.
Idempotency: Receivers must handle duplicate deliveries. Include a unique event_id in every webhook. Receivers store processed event IDs and skip duplicates. Your documentation should clearly state that webhooks have at-least-once delivery semantics.
Event payload design:
- Include the full resource state (“fat events”) so receivers don’t need to call back to your API
- OR include only the event type and resource ID (“thin events”) and let receivers fetch the current state. Thin events are simpler but require an API call per webhook.
- Best practice: include the changed fields and the event type. Receivers can process directly or fetch if they need more context.
Versioning: Include an API version in the webhook payload or URL path. When you change the payload schema, maintain backward compatibility or introduce a new version. Customers choose which version they receive.
Real-World Examples
Stripe
Industry-standard webhook implementation. HMAC-SHA256 signatures with timestamp. Retries over 72 hours with exponential backoff. Dashboard showing delivery attempts with full request/response details. Supports multiple webhook endpoints per account with event type filtering.
GitHub
Webhook deliveries for repository events (push, PR, issue). Each delivery logged with request/response. Redeliver button in the UI. Supports both HMAC-SHA256 and HMAC-SHA1 signatures. Ping event sent on endpoint creation for verification.
Shopify
Mandatory webhook verification for apps. Uses HMAC-SHA256 with the app secret. Webhooks are registered per-topic (orders/create, products/update). Automatic removal of endpoints that fail consistently for 19 days.
Svix
Managed webhook service used by companies like Clerk and Liveblocks. Provides SDKs for both sending and receiving. Built-in endpoint management portal that can be embedded in your dashboard. Handles retry, signing, and delivery monitoring.
Architectural Tradeoffs
Fat events (full payload) vs thin events (ID only)
Pros
- +Fat: receiver doesn't need API callback, lower latency
- +Thin: smaller payload, always current state (not stale snapshot)
- +Fat: works even if your API is temporarily down
Cons
- −Fat: larger payloads, potential data consistency issues if state changes between event and delivery
- −Thin: requires an API call per webhook, adds load to your API
- −Fat: harder to handle schema changes without breaking receivers
Self-built vs managed webhook service (Svix)
Pros
- +Self-built: full control, no per-event cost, data stays internal
- +Managed: faster to implement, battle-tested delivery infrastructure
- +Managed: customer-facing portal included
Cons
- −Self-built: significant engineering effort (3-6 weeks for a solid system)
- −Managed: per-event pricing, vendor dependency
- −Self-built: must handle all edge cases (retry, signing, circuit breaking)
Guaranteed ordering vs parallel dispatch
Pros
- +Ordered: events arrive in logical sequence, simpler receiver logic
- +Parallel: much higher throughput, lower latency
- +Parallel with sequence numbers: best throughput, receivers reorder if needed
Cons
- −Ordered: per-endpoint FIFO limits throughput to one delivery at a time
- −Parallel: out-of-order delivery, receivers must handle reordering
- −Sequence numbers: adds complexity to both sender and receiver
Learn Webhooks
Copy a learning context prompt for an AI assistant. It keeps assumptions visible and asks for tradeoffs, cost drivers, failure modes, and what to measure before adding complexity.
Explore More Capabilities
API Versioning
Backward-compatible API evolution with URL, header, and content negotiation strategies
Audit Logging
Append-only event stores, tamper-proof records, and compliance-ready activity trails
Caching Strategies
Cache-aside, write-through, invalidation patterns, and distributed caching with Redis