Queues gets a distributed overhaul
Cloudflare Queues has been generally available since Birthday Week 2024, and with that release came a significant architectural shift. The service that decouples Workers into event-driven producers and consumers moved from a single Durable Object per queue to a horizontally scaled design spread across multiple Durable Objects. The result is a substantial jump in performance: median write latency dropped from roughly 200 ms to 60 ms, per-queue throughput climbed from 400 to 5,000 messages per second, and maximum consumer concurrency went from 20 to 250 invocations.
The original v1 design favored speed to market. Rather than standing up infrastructure for an off-the-shelf system like Kafka or Pulsar, the team built Queues on Durable Objects, which handle routing, storage, and durability on the platform. Each queue was a single Durable Object hosted in Western North America, close to Cloudflare's centralized configuration API. That kept things simple but created three bottlenecks: global message latency, a single-threaded throughput ceiling around 400 messages per second, and consumer concurrency limited by Durable Object subrequest caps.
Delivering messages in v1
In the v1 flow, a client POSTed a message to /accounts/:accountID/queues/:queueID/messages. A Queue Broker Worker handled authentication and used Durable Objects' idFromName API to route the request to the queue's single Durable Object, which persisted the message before returning success. The platform handled redundant storage automatically.
On the consumption side, each queue Durable Object kept an alarm that fired when full batches were ready or when a partial batch hit the user's max wait time. The alarm woke the object, which pulled batches from storage and sent them to a Dispatcher Worker. That worker used Workers for Platforms dynamic dispatch to invoke the user's queue() function in their Consumer Worker.
That architecture allowed Cloudflare to launch the Beta and iterate, but the single-object-per-queue model was inherently constrained. A Durable Object is single-threaded and has a fixed request-processing capacity, and its concurrent subrequest limits capped how many queue() invocations could run in parallel.
Scaling out in v2
The v2 architecture replaces one Durable Object per queue with many. Storage Shard Durable Objects are now deployed across all available regions, with multiple shards per region to load balance incoming requests. That removes both the geographic penalty of routing everything through Western North America and the throughput cap of a single object.
The write path still starts with a POST to the same Queues API endpoint. The Broker Worker authenticates, then reads from Workers KV to get a shard map listing available storage shards for the region and queueID. It randomly picks a shard and routes to it via idFromName. The chosen shard persists the message and confirms. Workers KV acts as the fast metadata store for this lookup, keeping the shard map globally cached.
Consumer throughput gets the same treatment. A new Consumer Shard Durable Object class can be scaled horizontally, sidestepping the subrequest limits that held v1 to 20 concurrent invocations. Each Consumer maintains an alarm, is notified by a Coordinator when messages are ready, and sets the alarm to fire immediately. It then consults the shard map for storage shards with available messages, pulls a batch from a randomly selected one, dispatches it to the Consumer Worker, and sends an acknowledgment or retry back to the storage shard.
The role of the Coordinator
Between the data plane and the user sits a Control Plane, anchored by a Coordinator Durable Object that acts as the brain of each queue. Queue creation and settings changes go through it. The Coordinator maintains the shard map, which tracks every Durable Object in the queue: its region, available message count, and estimated load. It periodically writes a fresh copy to Workers KV so the Broker Worker can read it quickly and route messages to the right shard.
All storage and consumer shards send heartbeats to the Coordinator with message counts and current request rates. The Coordinator uses that data for autoscaling. If a region's shards are overloaded, it provisions more and adds them to the KV shard map; the Broker Worker naturally spreads load across the new shards. If the message backlog grows, the Coordinator adds Consumer shards to increase delivery throughput.
That distributed design is what unlocked the GA numbers. Moving from a single, centrally hosted object to a regional, multi-shard layout is what brought write latency down to 60 ms and raised queue throughput to 5,000 messages per second.
Roadmap after GA
Cloudflare plans to build on the new architecture by adopting the beta version of Durable Objects backed by SQLite to push throughput and latency further. Near-term feature work includes message management: purging a queue, pausing consumption, and redriving messages between queues, such as moving Dead Letter Queue messages back to the original queue. Longer term, Queues is positioned as the event hub for the platform, with work toward low-friction ingestion of events from other Cloudflare services alongside multi-consumer support so a queue is no longer limited to a single Consumer.



