Queues
Private network built for autonomous agents
One connector, one binary for your devices, servers, VPCs, and Workers on one private network, routed through Cloudflare's global network across 330+ cities.
Your private network across Region: Earth
Integrate with Workers
Security built-in
One private network for all your agents, services and clients

Install the connector
One binary for laptops, Workers, or servers. No complex VPN setup, no relay servers. Just install and connect.

Join the mesh
Your device gets a private IP on the mesh network automatically. Configure routes and policies from the dashboard.

Routed through 330+ cities
Traffic flows through Cloudflare's global network, the same infrastructure handling 20% of Internet traffic.

Reach any private service
Call databases, APIs, and internal hosts by private IP. Zero public endpoints exposed, with Zero Trust policies built in.

Pull-consumers
Gain granular control over message consumption from anywhere on the public Internet by having your services explicitly pull messages and acknowledge them upon successful processing.
Queues Built for how agents actually work
Agents don't follow human workflows. They call APIs, query databases, and coordinate with other agents autonomously. Mesh gives them the private network they need.
View docsCoding agents on private infra
Workers calling private databases
Multi-agent coordination
How it all fits together
Agents on your laptop, Workers in the cloud, databases in your VPC. All addressed by private IP, all routed through one network.
// Producer Worker - Send messages to queueexport default { async fetch(request, env) { const { searchParams } = new URL(request.url); const message = searchParams.get('message');
if (!message) { return new Response('Missing message parameter', { status: 400 }); }
// Send message to queue await env.MY_QUEUE.send({ message: message, timestamp: new Date().toISOString(), userId: request.headers.get('X-User-ID'), });
return new Response('Message sent to queue', { status: 200 }); },};
// Consumer Worker - Process messages from queueexport default { async queue(batch, env, ctx) { for (const message of batch.messages) { try { // Process the message console.log('Processing message:', message.body);
// Simulate some work await new Promise((resolve) => setTimeout(resolve, 1000));
// Acknowledge the message message.ack(); } catch (error) { console.error('Failed to process message:', error); message.retry(); } } },};// Data ingestion workerexport default { async fetch(request, env) { const data = await request.json();
// Send data to ETL queue for processing await env.ETL_QUEUE.send({ type: 'data_ingestion', payload: data, timestamp: new Date().toISOString(), source: 'api', });
return new Response('Data queued for processing', { status: 200 }); },};
// ETL processing workerexport default { async queue(batch, env, ctx) { for (const message of batch.messages) { try { const { type, payload } = message.body;
if (type === 'data_ingestion') { // Transform the data const transformedData = await transformData(payload);
// Store in data warehouse await env.DATA_WAREHOUSE.prepare( 'INSERT INTO processed_data (data, processed_at) VALUES (?, ?)', ) .bind(JSON.stringify(transformedData), new Date().toISOString()) .run(); }
message.ack(); } catch (error) { console.error('ETL processing failed:', error); message.retry(); } } },};
async function transformData(data) { // Your data transformation logic here return { ...data, processed: true, transformedAt: new Date().toISOString(), };}// URL discovery workerexport default { async fetch(request, env) { const { searchParams } = new URL(request.url); const startUrl = searchParams.get('url');
if (!startUrl) { return new Response('Missing URL parameter', { status: 400 }); }
// Add initial URL to crawl queue await env.CRAWL_QUEUE.send({ url: startUrl, depth: 0, maxDepth: 3, });
return new Response('Crawling started', { status: 200 }); },};
// Crawler workerexport default { async queue(batch, env, ctx) { for (const message of batch.messages) { try { const { url, depth, maxDepth } = message.body;
// Fetch the page const response = await fetch(url); const html = await response.text();
// Extract links const links = extractLinks(html, url);
// Process the page content await processPage(url, html);
// Add new links to queue if within depth limit if (depth < maxDepth) { for (const link of links) { await env.CRAWL_QUEUE.send({ url: link, depth: depth + 1, maxDepth: maxDepth, }); } }
message.ack(); } catch (error) { console.error('Crawling failed:', error); message.retry(); } } },};
function extractLinks(html, baseUrl) { // Simple link extraction logic const linkRegex = /<a[^>]+href=["']([^"']+)["'][^>]*>/gi; const links = []; let match;
while ((match = linkRegex.exec(html)) !== null) { const href = match[1]; const absoluteUrl = new URL(href, baseUrl).toString(); links.push(absoluteUrl); }
return links;}
async function processPage(url, html) { // Your page processing logic here console.log(`Processed page: ${url}`);} Queues Pricing
Reliable message processing. View Storage & Data pricing details
Standard Operations
10,000 operations/day included
$0.40 / million operations
SiteGPT
"
We use Cloudflare for everything – storage, cache, queues, and most importantly for training data and deploying the app on the edge, so I can ensure the product is reliable and fast. It's also been the most affordable option, with competitors costing more for a single day's worth of requests than Cloudflare costs in a month. "
Powerful primitives, seamlessly integrated
Built on systems powering 20% of the Internet, Queues run on the same infrastructure Cloudflare uses to build Cloudflare. Enterprise-grade reliability, security, and performance are standard.
Build without boundaries
Join thousands of developers who've eliminated infrastructure complexity and deployed globally with Cloudflare. Start building for free — no credit card required.