Cloudflare Queues Alternatives for Webhooks: Hookdeck Event Gateway, Convoy, and Cloud Queues Compared
Cloudflare Queues gives Workers developers a message queue with batching, retries, delays, and dead letter queues for $0.40 per million operations. If your application already runs on Workers, it is the obvious way to decouple webhook receipt from webhook processing: a producer Worker accepts the HTTP POST, verifies the signature, and calls queue.send(); a consumer Worker processes messages in batches on the other side.
That architecture works. The question this page addresses is what the producer and consumer Workers end up owning, because Cloudflare Queues was designed as a general-purpose queue for Workers applications, not as webhook infrastructure. Signature verification for each provider, idempotency handling, and per-event visibility all live in your code. Hookdeck Event Gateway is a managed webhook gateway that replaces the queue and the code around it for the webhook path specifically. This page compares the two, including the cases where Cloudflare Queues remains the right choice.
How to evaluate a Cloudflare Queues alternative for webhooks
Six dimensions matter when the workload is inbound webhooks rather than internal messaging:
- Webhook-aware features. Does the platform verify provider signatures, deduplicate events, and support per-source replay, or do you build those in the producer and consumer Workers?
- Retry semantics. Cloudflare Queues retries at the queue level: a maximum retry count and an optional delay, applied uniformly. Webhook delivery benefits from per-endpoint policies, response-code rules, and
Retry-Afterawareness. - Dead letter handling. A DLQ in Cloudflare Queues is another queue. Reading, diagnosing, and re-driving its contents requires another consumer. Compare that with failed events as searchable records you can inspect and replay.
- Delivery guarantees and deduplication. Cloudflare Queues is at-least-once, and the documentation recommends handling duplicates yourself with idempotency keys. Webhook providers also redeliver. Does the platform absorb that, or does your consumer?
- Observability. Cloudflare Queues exposes aggregate metrics (backlog size, consumer concurrency, operation counts) through the dashboard and GraphQL API. There is no per-message search, inspection, or replay. For webhooks, "which Stripe event failed and why" is the question you actually ask.
- Platform coupling. Push consumers must be Workers. Pull consumers let external infrastructure poll over HTTP, but then you own the polling loop, visibility timeouts, and acknowledgment logic.
What Cloudflare Queues does for webhooks today
The standard pattern
The common architecture: a producer Worker bound to a queue receives the webhook, verifies the signature (Stripe's SDK, Shopify's HMAC check, or hand-rolled crypto for less common providers), and enqueues the payload. A consumer Worker receives batches of up to 100 messages, processes each one, and ack()s or retry()s individually. Failures beyond the retry limit route to a dead letter queue, if you configured one.
flowchart LR
A[Provider] --> B[Producer Worker verify, enqueue]
B --> C[Cloudflare Queue batch, retry]
C --> D[Consumer Worker process, ack/retry]
D --> E[Your logic]
C -->|max retries exceeded| F[Dead letter queue]
Why teams pick it
Teams pick it for three good reasons. First, if you're on Workers, there is nothing to provision: a queue is a binding in wrangler.toml. Second, the pricing is hard to argue with: $0.40 per million operations, a million free each month on the $5 Workers Paid plan, and no egress charges. A million webhooks a day costs roughly $36 a month in queue operations. Third, retries, delays, batching, and DLQs are built in, which is more than a bare HTTP handler gives you.
Where it falls short for webhooks specifically
The producer Worker owns all webhook logic. Cloudflare Queues has no concept of a Stripe source versus a GitHub source; verification code for every provider you integrate lives in your Worker, along with the test coverage and the key rotation handling. The same applies to idempotency: delivery is at-least-once, there is no built-in deduplication, and Cloudflare's own documentation recommends generating idempotency keys and deduplicating downstream. Since webhook providers also redeliver on timeouts, your consumer defends against duplicates from two directions.
Observability is aggregate. You can chart backlog depth and consumer concurrency, but you cannot search for a specific event, inspect its payload in flight, or replay it after fixing a consumer bug. When a customer reports a missing order webhook, the trail is whatever your Workers logged. The DLQ is similarly opaque: it's a queue, so its contents are invisible until you write a consumer to drain it, and once messages expire (up to 14 days on the paid plan, 24 hours on free) they're gone.
Retry policy is uniform per queue: a retry count (up to 100) and a delay (up to 24 hours). There are no response-code rules, no exponential backoff configuration per destination, and no Retry-After handling unless you implement it with explicit retry({ delaySeconds }) calls in consumer code.
Finally, the platform limits are worth knowing before a webhook storm finds them for you: 128 KB maximum message size (large payloads need R2 or truncation), 5,000 messages per second per queue, and 250 concurrent push consumer invocations.
For more on the pattern and its trade-offs, see managed webhook gateway vs. DIY queue-backed infrastructure and how to implement webhook idempotency.
Cloudflare Queues alternatives for webhooks
Hookdeck Event Gateway
Hookdeck Event Gateway replaces the producer Worker, the queue, and the retry scaffolding for the webhook path. Webhooks arrive at a Hookdeck source URL, get verified against 160+ pre-configured provider schemes, are queued durably, and are delivered to your destination, which can still be a Cloudflare Worker. Your Worker goes back to being application logic.
| Capability | Hookdeck Event Gateway | Cloudflare Queues |
|---|---|---|
| Webhook ingestion + signature verification | ✅ 160+ sources pre-configured | ❌ Build it in the producer Worker |
| Public HTTP endpoint | ✅ Provided per source | ❌ Via a producer Worker route |
| Deduplication | ✅ Configurable window (1s–1h), field-based | ❌ Client-side idempotency keys |
| Retry policy | ✅ Per-connection: exponential, linear, or custom; response-code rules; Retry-After support | ℹ️ Per-queue retry count + delay; manual retry({ delaySeconds }) |
| Failed event handling | ✅ Issues group failures; events searchable and replayable | ℹ️ DLQ (another queue; needs its own consumer) |
| Replay individual events | ✅ One-click and bulk | ❌ Custom DLQ consumer |
| Full-text event search | ✅ | ❌ Aggregate metrics only |
| In-flight transformation | ✅ JavaScript transformations | ❌ In consumer code |
| Filtering | ✅ Rule-based, before delivery | ❌ In consumer code |
| Rate limiting to destination | ✅ Per-destination throughput control | ℹ️ Consumer concurrency settings |
| Raw queue cost at volume | ℹ️ Event-based pricing, free tier then paid plans | ✅ $0.40/million operations, no egress fees |
| Works outside Workers | ✅ Any HTTP destination | ℹ️ Pull consumers over HTTP; push requires Workers |
| Self-hostable | ❌ | ❌ Managed Cloudflare |
| Suits non-webhook messaging | ❌ | ✅ |
The honest cost comparison: at raw queue-operation prices, Cloudflare Queues is cheaper. Hookdeck's pricing is per event, and at high volumes the bill will exceed what Cloudflare charges for the equivalent operations. What you're buying is the layer Cloudflare doesn't provide, which otherwise exists as Worker code you write, test, and maintain. Whether that trade is worth it depends on how much webhook-specific code you're carrying and how often you debug it.
Hookdeck delivers to Workers the same way any HTTP client does, so keeping your processing on Cloudflare is unchanged. There's a walkthrough at how to receive and replay external webhooks in Cloudflare with Hookdeck.
Replace Cloudflare Queues for the webhook path
Hookdeck Event Gateway gives you ingestion, signature verification, deduplication, retries, and replay, delivering to your Workers unchanged
Convoy
Convoy is an open-source, self-hosted webhook gateway. If your reason for being on Cloudflare Queues is cost control or a preference for owning infrastructure, Convoy keeps that property while adding webhook-specific features Cloudflare Queues lacks: retries with backoff, an event log, and delivery attempt visibility. The trade-offs are a smaller pre-configured source library than Hookdeck, no integrated full-text search or JavaScript transformations, and the operational load of running Postgres and Redis yourself, a notable step up from a wrangler.toml binding.
AWS SQS, Google Pub/Sub
Moving from Cloudflare Queues to SQS or Pub/Sub trades one general-purpose queue for another. You gain higher throughput ceilings, broader tooling, and (with SQS FIFO) built-in deduplication within a fixed five-minute window, and you give up Cloudflare's zero-egress pricing and Workers integration. The webhook-specific gaps are identical: no signature verification, no per-event replay, no source awareness. If Cloudflare Queues isn't working for your webhooks, these are lateral moves rather than solutions. See AWS SQS alternatives for webhooks for the same analysis applied to SQS.
Staying on Workers without queues
Some teams process webhooks synchronously in a Worker and skip the queue entirely. This works until a provider retries into a slow downstream API, or a webhook storm arrives faster than your database accepts writes. The queue exists for good reasons; the argument of this page is only that a generic queue leaves the webhook-specific work to you. What to consider when using message queues for webhooks covers the pattern in depth.
When to keep Cloudflare Queues
Cloudflare Queues is the right choice in several situations:
- Webhooks are a small slice of a larger Workers async workload. If the same queues drive image processing, notification fan-out, and internal events, consolidating on Queues is reasonable. Don't add a vendor for one traffic type.
- Your team is deeply committed to the Workers platform. Bindings,
wranglerdeploys, and local development with Miniflare are a coherent workflow. A single producer Worker handling one or two providers with stable, tested verification code is not a maintenance burden worth re-architecting. - Volume is low and stable, and failures are rare. The observability gap matters in proportion to how often you debug deliveries. If the DLQ has been empty for six months, per-event search is a feature you don't need yet.
- Cost dominates every other concern. At millions of events per day with thin margins, $0.40 per million operations and zero egress is a real advantage, and building the webhook layer in Workers code may be the correct economic decision.
The migration argument gets stronger as provider count grows, when the producer Worker accumulates verification code for its fifth provider, when someone spends an afternoon writing a one-off DLQ drain script, or when "did we get that webhook?" becomes a recurring support question with no good answer.
Migrating from Cloudflare Queues to Hookdeck Event Gateway
Run the two pipelines in shadow mode first. Point one provider's webhook URL at a Hookdeck source, set the destination to a new route on your existing consumer Worker, and leave the Queues pipeline running for the rest. Compare delivery behavior, watch retries and Issues in the Hookdeck dashboard, and confirm your Worker handles Hookdeck's delivery headers. Then cut over providers one at a time; webhook URLs change in each provider's dashboard, so rollback is a URL change too.
Cloudflare Queues stays where it's good: internal messaging between Workers. Nothing about the migration requires leaving the Workers platform; Hookdeck sits in front of it.
During development, hookdeck listen 3000 forwards events from a Hookdeck source to a local server, replacing the deploy-to-test loop with wrangler dev for webhook work.
Hookdeck Event Gateway is the managed answer for webhooks
The gap in Cloudflare Queues shows up in code: producer Workers repeating signature verification per provider, and a DLQ whose drain script gets written during an incident. Hookdeck Event Gateway moves those concerns out of your Workers and into a managed webhook gateway with one observability surface for every event that passes through. Your Workers keep doing what they're for.
Try Hookdeck Event Gateway for free
Webhook-aware ingestion, durable queueing, retries, and per-event replay, delivering to Cloudflare Workers or any HTTP endpoint
FAQs
What is the best alternative to Cloudflare Queues for webhooks?
For a managed service, Hookdeck Event Gateway: it adds signature verification, deduplication, per-event search, and replay that Cloudflare Queues doesn't provide. For self-hosting, Convoy. Moving to SQS or Pub/Sub swaps one generic queue for another without closing the webhook-specific gaps.
Can Hookdeck deliver webhooks to Cloudflare Workers?
Yes. A Worker route is an HTTP endpoint like any other. The common migration keeps the consumer Worker and replaces the producer Worker and queue with Hookdeck.
Is Cloudflare Queues cheaper than Hookdeck?
On raw per-message cost, yes: $0.40 per million operations with no egress fees is less than Hookdeck's event-based pricing at equivalent volume. The comparison changes when you price the Worker code for verification, idempotency, replay tooling, and the debugging time the missing observability costs.
Does Cloudflare Queues deduplicate messages?
No. Delivery is at-least-once, and Cloudflare's documentation recommends client-side idempotency keys. Hookdeck supports configurable field-based deduplication windows from one second to one hour.
Can I keep Cloudflare Queues for internal messaging and use Hookdeck for webhooks?
That's the recommended hybrid. Hookdeck handles ingestion, verification, and delivery of third-party webhooks; Queues continues to handle Worker-to-Worker async work where it fits well.
How do I replay a failed webhook in Cloudflare Queues?
There's no built-in way to replay an individual message. Failed messages route to a dead letter queue if configured, and you write a consumer to read and re-enqueue them before retention expires. In Hookdeck, failed events are searchable records with one-click and bulk replay.