Skip to content
Development
Skill

/cloudflare-queues

This skill should be used when the user asks to \"set up Cloudflare Queues\", \"create a message queue\", \"implement queue consumer\", \"process background jobs\", \"configure queue retry logic\", \"publish messages to queue\", \"implement dead letter queue\", or encountering

From plugin
secondsky-claude-skills
241183 skills42 agents62 commands2 MCP

Claude Code

$ npx -y skills add secondsky/claude-skills --skill cloudflare-queues --agent claude-code

SKILL.md

cloudflare-queues.SKILL.md
name: cloudflare-queues
description: "This skill should be used when the user asks to \"set up Cloudflare Queues\", \"create a message queue\", \"implement queue consumer\", \"process background jobs\", \"configure queue retry logic\", \"publish messages to queue\", \"implement dead letter queue\", or encountering \"queue timeout\", \"message retry\", \"throughput exceeded\", \"queue backlog\" errors."
license: MIT
metadata:
  version: "3.0.0"
  wrangler_version: "4.81.0"
  workers_types_version: "4.20260408.0"
  last_verified: "2025-12-27"
  errors_prevented: 10
  templates_included: 6
  references_included: 11
  agents_included: 2
  commands_included: 3
  keywords:
    - cloudflare queues
    - queues workers
    - message queue
    - queue bindings
    - async processing
    - background jobs
    - queue consumer
    - queue producer
    - batch processing
    - dead letter queue
    - dlq
    - message retry
    - queue ack
    - consumer concurrency
    - queue backlog
    - wrangler queues

Cloudflare Queues

**Status**: Production Ready ✅ | **Last Verified**: 2025-12-27

**Dependencies**: cloudflare-worker-base (for Worker setup)

**Contents**: [Quick Start](#quick-start-10-minutes) • [Critical Rules](#critical-rules) • [Top Errors](#top-3-critical-errors) • [Use Cases](#common-use-cases) • [When to Load References](#when-to-load-references) • [Limits](#limits--quotas)

---

Quick Start (10 Minutes)

1. Create Queue

bunx wrangler queues create my-queue
bunx wrangler queues list

2. Producer (Send Messages)

**wrangler.jsonc:**

{
  "name": "my-producer",
  "main": "src/index.ts",
  "queues": {
    "producers": [
      {
        "binding": "MY_QUEUE",
        "queue": "my-queue"
      }
    ]
  }
}

**src/index.ts:**

import { Hono } from 'hono';

type Bindings = {
  MY_QUEUE: Queue;
};

const app = new Hono<{ Bindings: Bindings }>();

app.post('/send', async (c) => {
  await c.env.MY_QUEUE.send({
    userId: '123',
    action: 'process-order',
    timestamp: Date.now(),
  });

  return c.json({ status: 'queued' });
});

export default app;

3. Consumer (Process Messages)

**wrangler.jsonc:**

{
  "name": "my-consumer",
  "main": "src/consumer.ts",
  "queues": {
    "consumers": [
      {
        "queue": "my-queue",
        "max_batch_size": 10,
        "max_retries": 3,
        "dead_letter_queue": "my-dlq"
      }
    ]
  }
}

**src/consumer.ts:**

import type { MessageBatch } from '@cloudflare/workers-types';

export default {
  async queue(batch: MessageBatch): Promise<void> {
    for (const message of batch.messages) {
      console.log('Processing:', message.body);
      // Your logic here
    }
    // Implicit ack: returning successfully acknowledges all messages
  },
};

**Deploy:**

bunx wrangler deploy

**Load**: `references/setup-guide.md` for complete 6-step setup with DLQ configuration

---

Critical Rules

Always Do ✅

1. **Configure Dead Letter Queue** for production queues 2. **Use explicit ack()** for non-idempotent operations (DB writes, API calls) 3. **Validate message size** before sending (<128 KB) 4. **Use sendBatch()** for multiple messages (more efficient) 5. **Implement exponential backoff** for retries 6. **Set appropriate batch settings** based on workload 7. **Monitor queue backlog** and consumer errors 8. **Use ctx.waitUntil()** for async cleanup in consumers 9. **Handle errors gracefully** - log, alert, retry 10. **Let concurrency auto-scale** (don't set max_concurrency unless needed)

Never Do ❌

1. **Never assume message ordering** - not guaranteed FIFO 2. **Never rely on implicit ack for non-idempotent ops** - use explicit ack() 3. **Never send messages >128 KB** - will fail 4. **Never delete queues with active messages** - data loss 5. **Never skip DLQ configuration** in production 6. **Never exceed 5000 msg/s per queue** - rate limit error 7. **Never process messages synchronously in loop** - use Promise.all() 8. **Never ignore message.attempts** - use for backoff logic 9. **Never set max_concurrency=1** unless you have a very specific reason 10. **Never forget to ack()** in explicit acknowledgement patterns

---

Top 3 Critical Errors

Error #1: Message Too Large

**Problem**: Message exceeds 128 KB limit

**Solution**: Store large data in R2, send reference

// ❌ Wrong
await env.MY_QUEUE.send({ data: largeArray }); // >128 KB fails

// ✅ Correct
const message = { data: largeArray };
const size = new TextEncoder().encode(JSON.stringify(message)).length;

if (size > 128000) {
  const key = `messages/${crypto.randomUUID()}.json`;
  await env.MY_BUCKET.put(key, JSON.stringify(message));
  await env.MY_QUEUE.send({ type: 'large-message', r2Key: key });
} else {
  await env.MY_QUEUE.send(message);
}

Error #2: Throughput Exceeded

**Problem**: Exceeding 5000 messages/second per queue

**Solution**: Use sendBatch() and rate limiting

// ❌ Wrong
for (let i = 0; i < 10000; i++) {
  await env.MY_QUEUE.send({ id: i }); // Too fast!
}

// ✅ Correct
const messages = Array.from({ length: 10000 }, (_, i) => ({
  body: { id: i },
}));

// Send in batches of 100
for (let i = 0; i < messages.length; i += 100) {
  await env.MY_QUEUE.sendBatch(messages.slice(i, i + 100));
}

Error #3: Entire Batch Retried When One Message Fails

**Problem**: Single message failure causes all messages to retry

**Solution**: Use explicit acknowledgement

// ❌ Wrong - implicit ack
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      await env.DB.prepare('INSERT INTO orders VALUES (?, ?)').bind(
        message.body.id,
        message.body.amount
      ).run();
    }
    // If any fails, ALL retry!
  },
};

// ✅ Correct - explicit ack
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (con
Read more
@secondsky
Ships withsecondsky-claude-skills

145 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).

241183 skills42 agents2 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
241
Star history of secondsky/claude-skills on GitHub, a chart by star-history.com

Other skills on secondsky-claude-skills.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about cloudflare-queues.

Which coding agents can use cloudflare-queues?
cloudflare-queues installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.