| [ Web Proxy ] |
| Viewing: https://www.cloudflare.com/products/queues/ | [Back] [Original] |
Queues
Guaranteed delivery
At least once delivery helps you balance message retention and end-to-end latency.
Improved visibility
See metrics on queue backlogs, consumer concurrency, and message operations.
Cost efficiency
Move messages and data around or outside your environment with no egress fees.
[Background Pattern] Queues Simplify message processing and data movement across a variety of use cases.
View docsProcess customer messages
Send, list, and acknowledge messages across multiple queues.Simplify LLM calling
Batch requests in order to reduce inference costs.Protect downstream APIs
Queues can enforce rate limiting rules in order to preserve system availability.Agents on your laptop, Workers in the cloud, databases in your VPC. All addressed by private IP, all routed through one network.
[Background Pattern] // 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}`);}Basic Queue Operations
Send messages to a queue and process them asynchronously.ETL Pipeline with Queues
Build reliable ETL pipelines by buffering data through queues.Web Crawler with Queues
Build distributed web crawlers using queues to manage URL processing.SiteGPT
Reliable message processing. View Storage & Data pricing details
Standard Operations
10,000 operations/day included
$0.40 / million operations
Join thousands of developers who've eliminated infrastructure complexity and deployed globally with Cloudflare. Start building for free no credit card required.
| Web Proxy Viewer | New URL | Original Page |