High-performance job queue for Bun. Built for AI agents and automation.
Zero external infrastructure. MCP-native. TypeScript-first.
Documentation · Quick Start · Benchmarks · npm
bun add bunqueueimport { Bunqueue } from 'bunqueue/client';
const app = new Bunqueue('emails', {
embedded: true,
dataPath: './data/emails.db', // omit to run in-memory (lost on restart)
processor: async (job) => {
console.log(`Sending to ${job.data.to}`);
return { sent: true };
},
});
await app.add('send', { to: 'alice@example.com' });That's it. Queue + Worker in one object, persisted to a single SQLite file.
No Redis, no config, no setup. The install is 5.5 MB, 7 packages, 2 runtime
dependencies (croner + msgpackr) — SQLite, S3, HTTP and WebSocket are Bun
built-ins.
The queue also runs as a standalone server — one command, nothing else to operate:
# in-memory without --data-path; pass it to persist jobs to SQLite
bunx bunqueue start --data-path ./data/bunq.db # TCP :6789, HTTP :6790
# or, with no runtime at all (the volume persists /app/data):
docker run -d -p 6789:6789 -p 6790:6790 \
-v bunqueue-data:/app/data \
ghcr.io/egeominotti/bunqueue:latestThen produce and process from the language you already use:
npm install bunqueue-client # Node.js ≥ 20, Deno ≥ 2, Bun, Cloudflare Workersimport { Queue, Worker } from 'bunqueue-client';
const queue = new Queue('emails'); // localhost:6789 by default
await queue.add('welcome', { to: 'user@example.com' });
new Worker('emails', async (job) => ({ sent: true }), { concurrency: 10 });Python, PHP, Go, Rust and Elixir clients speak the same protocol — see One Queue, Any Language.
Only the server and embedded mode are Bun-only (
bun >= 1.3.9, bun.sh); producers and workers can run anywhere.
| Library | Requires | AI-native |
|---|---|---|
| BullMQ | Redis | No |
| Agenda | MongoDB | No |
| pg-boss | PostgreSQL | No |
| bunqueue | Nothing | Yes |
- Zero external infrastructure — one process, one SQLite file.
cpto back up - BullMQ-compatible API — same
Queue,Worker,QueueEvents; migrating takes minutes - MCP server included — 73 tools; AI agents get full queue control out of the box
- Everything server-side — retries with backoff, priorities, cron, rate limits, dead letter queue
- Up to 630K ops/sec — verified benchmarks with methodology
Great for: single-server deployments, AI agents that need a scheduler, prototypes and MVPs, embedded use cases (CLI tools, edge, serverless), teams that don't want to operate Redis.
Not ideal for: multi-region distributed systems requiring HA or automatic failover today. If you already run Redis and BullMQ works for you, keep it.
| Embedded | Server (TCP) | |
|---|---|---|
| How it works | Queue runs inside your process | Standalone server, clients connect via TCP |
| Setup | bun add bunqueue |
docker run or bunqueue start |
| Performance | 630K ops/sec (bulk push) | 90K ops/sec (push) |
| Best for | Single-process apps, CLIs, serverless | Multiple workers, separate producer/consumer |
| Scaling | Same process only | Multiple clients across machines |
Everything in your process. Without a data path the queue is in-memory: pass
dataPath (or set BUNQUEUE_DATA_PATH) to persist jobs.
import { Queue, Worker } from 'bunqueue/client';
const queue = new Queue('emails', { embedded: true, dataPath: './data/app.db' });
const worker = new Worker(
'emails',
async (job) => {
return { sent: true };
},
{ embedded: true }
);
await queue.add('welcome', { to: 'user@example.com' });docker run -d -p 6789:6789 -p 6790:6790 \
-v bunqueue-data:/app/data \
ghcr.io/egeominotti/bunqueue:latestimport { Queue, Worker } from 'bunqueue/client';
const queue = new Queue('tasks', { connection: { host: 'localhost', port: 6789 } });
const worker = new Worker(
'tasks',
async (job) => {
return { done: true };
},
{ connection: { host: 'localhost', port: 6789 } }
);
await queue.add('process', { data: 'hello' });Running the server → · Deployment guide →
The server does all the heavy lifting. Official client SDKs speak the native TCP protocol with full feature parity, so producers and workers can live anywhere in your stack — add a job from TypeScript, process it from Python:
| Where your code runs | Install |
|---|---|
| Node.js ≥ 20, Deno ≥ 2, Bun, Cloudflare Workers | npm install bunqueue-client |
| Python ≥ 3.9 | pip install bunqueue-client |
| PHP ≥ 8.1 | composer require bunqueue/client |
| Go ≥ 1.26.5 | go get github.com/egeominotti/bunqueue/sdk/go |
| Rust ≥ 1.85 | cargo add bunqueue-client |
| Elixir ≥ 1.15 | Hex coming soon — today: use sdk/elixir as a path dependency |
// Node.js / Deno / Cloudflare Workers
import { Queue, Worker } from 'bunqueue-client';
const queue = new Queue('emails', { host: 'localhost', port: 6789 });
await queue.add('welcome', { to: 'user@example.com' });
new Worker('emails', async (job) => ({ sent: true }), { concurrency: 10 });# Python
from bunqueue import Queue, Worker
queue = Queue("emails", host="localhost", port=6789)
queue.add("welcome", {"to": "user@example.com"})
Worker("emails", lambda job: {"sent": True}, concurrency=10).run()Every SDK is certified against the same public wire protocol and conformance suite.
SDK guide (all six languages) →
Bunqueue bundles Queue + Worker + routes + middleware + cron in one object:
import { Bunqueue } from 'bunqueue/client';
const app = new Bunqueue('notifications', {
embedded: true,
routes: {
'send-email': async (job) => ({ sent: true }),
'send-sms': async (job) => ({ sent: true }),
},
concurrency: 10,
retry: { maxAttempts: 5, strategy: 'jitter' },
circuitBreaker: { threshold: 5, resetTimeout: 30000 },
});
// Onion middleware around every job
app.use(async (job, next) => {
const start = Date.now();
const result = await next();
console.log(`${job.name}: ${Date.now() - start}ms`);
return result;
});
await app.cron('daily-report', '0 9 * * *', { type: 'summary' });
await app.add('send-email', { to: 'alice@example.com' });
app.on('completed', (job, result) => console.log(result));
await app.close();Also included: batch processing, event triggers (job A completes → create job
B), job TTL, priority aging, deduplication, per-group rate limiting, DLQ with
auto-retry, graceful cancellation via AbortController.
Multi-step orchestration with saga compensation, branching, parallel steps and human-in-the-loop signals — built on bunqueue, no new infrastructure:
import { Workflow, Engine } from 'bunqueue/workflow';
const orderFlow = new Workflow('order-pipeline')
.step('reserve-stock', async () => {
await inventory.reserve();
return { reserved: true };
}, {
compensate: async () => await inventory.release(), // auto-rollback on failure
})
.step('charge', async () => {
return { txId: await payments.charge() };
}, {
compensate: async () => await payments.refund(),
})
.waitFor('manager-approval', { timeout: 86_400_000 }) // human-in-the-loop
.step('confirm', async (ctx) => {
return { txId: (ctx.steps['charge'] as { txId: string }).txId };
});
const engine = new Engine({ embedded: true });
engine.register(orderFlow);
const run = await engine.start('order-pipeline', { orderId: 'ORD-1' });
await engine.signal(run.id, 'manager-approval', { approved: true });| bunqueue | Temporal | Inngest | Trigger.dev | |
|---|---|---|---|---|
| Infrastructure | None (embedded) | PostgreSQL + 7 services | Cloud-only | Redis + PostgreSQL |
| Saga compensation | Built-in | Manual | Manual | Manual |
| Human-in-the-loop | .waitFor() |
Signals API | step.waitForEvent() |
Waitpoint tokens |
| Self-hosted | Zero-config | Complex | No | Complex |
| Pricing | Free (MIT) | Free / Cloud $$ | Per-execution | Free tier, then $50/mo+ |
Also included: nested workflows, doUntil/doWhile loops, forEach over
dynamic lists, schema validation (Zod, ArkType, Valibot or any .parse()),
step timeouts, typed events, SQLite-persisted execution state.
bunqueue ships a native MCP server: 73 tools, 5 resources, 3 prompts. Agents schedule cron jobs, push and process jobs, retry failures, set rate limits, and read stats — no glue code. HTTP handlers let an agent register a URL and have an embedded worker call it for every job.
bun add bunqueue @modelcontextprotocol/sdk # the MCP SDK is an optional peer
claude mcp add bunqueue -- bunx bunqueue-mcp// Claude Desktop / Cursor / Windsurf
{
"mcpServers": {
"bunqueue": {
"command": "bunx",
"args": ["--package=bunqueue", "bunqueue-mcp"]
}
}
}Then just ask: "Schedule a cleanup job every day at 3 AM" · "Show me all failed jobs and retry them" · "Set rate limit to 50/sec on api-calls".
A web dashboard that fully drives your server — queues, jobs, DLQ, cron, webhooks, workers, live activity, SQLite inspector and an AI copilot. Open source, currently in beta:
bunx bunqueue-dashboardbunqueue-demo.mp4
Live demo · User guide · GitHub
| Mode | Peak Throughput | Use Case |
|---|---|---|
| Embedded | 630K ops/sec (bulk push) | Same process |
| TCP | 90K ops/sec (push) | Distributed workers |
Run bun run bench to verify on your hardware.
Benchmark methodology →
- Quick Start — install to working queue in under a minute
- Queue API · Worker API — every option explained
- Simple Mode — routes, middleware, triggers, TTL, dedup
- Workflow Engine — sagas, branching, signals
- SDKs — TypeScript, Python, PHP, Go, Rust, Elixir
- MCP Server — AI agent integration
- Server & Deployment — Docker, TLS, auth, monitoring
- CLI Reference — run and manage from the terminal
- Migrate from BullMQ
MIT