The Queue Is a File: Zero-Infrastructure Job Queue
The queue
is a file.
bunqueue is a zero-infrastructure job queue: priorities, retries, cron, rate limits and a dead letter queue in one process, persisted to a single SQLite file. No Redis, no broker, nothing to operate.
Install bunqueue
bun add bunqueuenpm install bunqueue-clientbunx bunqueue start # the queue server, one commandnpm install bunqueue-client # produce jobs from fetch handlerspip install "git+https://github.com/egeominotti/bunqueue.git#subdirectory=sdk/python"MIT licensed · no signup, no server to run · same API on Node.js, Deno, Bun, Python and Cloudflare Workers
Pushing 100-job batches
throughput in ops/sec vs BullMQ + Redis, identical workloads
p99 push latency, lower is better
Apple M1 Max · Bun 1.3.14 · BullMQ 5.79.3 · Redis 8.8.0 · methodology · all benchmarks →
live simulation: higher priority jobs jump the line, failures retry with backoff, exhausted retries land in the dead letter queue
Write ten lines. Run.
Nothing to provision: the queue starts inside your process and persists itself to a SQLite file. From install to a working queue and worker in under a minute.
Write app.ts, a queue and a worker
import { Queue, Worker } from 'bunqueue/client';
const queue = new Queue('emails', { embedded: true });
new Worker('emails', async (job) => { console.log(`sending to ${job.data.to}`); return { sent: true };}, { embedded: true });
await queue.add('welcome', { to: 'user@example.com' }, { attempts: 3 });Run
bun app.ts# sending to user@example.comThat’s the whole setup. Retries, priorities, cron, rate limits and the dead letter queue are options on add(), and one dataPath option persists everything to a single SQLite file. Not on Bun? Same code with bunqueue-client against the server. Full quickstart
Same job, three fewer boxes.
BullMQ is excellent software that requires Redis. bunqueue removes the requirement: the queue lives in your process and persists to one file.
Running BullMQ
4 moving partsone of them stateful, on call
Running bunqueue
1 filecp to back up, sqlite3 to inspect
One queue, any language.
The server owns every queue semantic, so clients stay thin. Official SDKs speak the native TCP protocol with full feature parity, verified by the same test suite on every runtime.
TypeScript · Node, Deno, Bun
import { Queue, Worker } from 'bunqueue-client';
const queue = new Queue('emails');await queue.add('welcome', { to: 'a@b.co' });
new Worker('emails', async (job) => { await sendEmail(job.data); return { sent: true };}, { concurrency: 10 });npm install bunqueue-client · 100 e2e scenarios per runtime
Python
from bunqueue import Queue, Worker
queue = Queue("emails")queue.add("welcome", {"to": "a@b.co"}, attempts=3)
def process(job): send_email(job.data["to"]) return {"sent": True}
Worker("emails", process, concurrency=10).run()same API, snake_case · 66 e2e scenarios
Cloudflare Workers
import { Queue } from 'bunqueue-client';
export default { async fetch(req: Request, env: Env) { const q = new Queue('signups', { host: env.HOST, tls: true }); const job = await q.add('welcome', await req.json()); q.close(); return Response.json({ queued: job.id }); },};nodejs_compat flag, produce from fetch handlers · 16 scenarios inside workerd
CLI & AI agents
# push, watch, inspect from the terminalbunqueue push emails '{"to":"a@b.co"}' --priority 5bunqueue statsbunqueue dlq list emails
# or let an agent drive it: 73 MCP toolsclaude mcp add bunqueue -- bunx bunqueue-mcpMCP server for Claude, Cursor and any MCP client
See the queue move.
A web dashboard that fully drives your server: queues, jobs, DLQ, cron, webhooks, workers, live activity, a SQLite inspector and an AI copilot. One command: bunx bunqueue-dashboard.
user guide · github · npm
One process. One file.
Point dataPath at bunq.db and everything the queue knows lives there: jobs and their states, schedules, results, the dead letter queue. Back it up with cp, inspect it with sqlite3, ship it to S3 on a schedule. Your infrastructure diagram loses three boxes, and there is no version skew between the queue and its store.
production/ ├── app/ your services └── data/ └── bunq.db the entire queue · jobs waiting · active · completed · cron schedules and repeatables · dlq failed jobs, kept · results return values
A queue and a worker, ten lines.
Familiar Queue and Worker API, end to end TypeScript, and 3.5x the bulk push throughput of BullMQ measured on identical workloads, methodology below. Migrating takes minutes, the mental model is the same.
import { Queue, Worker } from 'bunqueue/client';
const queue = new Queue('emails', { embedded: true });
await queue.add('welcome', { to: 'user@example.com' }, { attempts: 3 });
const worker = new Worker('emails', async (job) => { await sendEmail(job.data); return { sent: true };}, { embedded: true, concurrency: 5 });
worker.on('completed', (job, result) => console.log(`done: ${job.id}`));Four tools, one file.
Everything a production queue needs, in the same process and the same SQLite file. Adopt one piece or all of them, each stands on its own.
Queue & Worker
BullMQ-familiar API for adding and processing jobs, end to end TypeScript.
await queue.add('welcome', data, { priority: 5 })Cron & schedulers
Repeatable jobs with cron patterns, intervals and timezones, persisted, never lost on restart.
await app.cron('daily', '0 9 * * *', data)Workflow engine
Multi-step orchestration with automatic rollback when a step fails.
new Workflow('order').step(...).parallel(...)Operations
Failed jobs are kept and retryable, metrics are scrapable, backups are scheduled.
bunx bunqueue-dashboard
Verified, secured, observable.
Tested on every runtime
- 100 e2e scenarios each on Node.js, Deno, Bun
- 16 scenarios inside workerd
- 66 scenarios in Python
- every public SDK method covered
Hardened by default
- token auth across TCP and HTTP
- native TLS or Unix domain sockets
- webhook SSRF validation built in
- security model & hardening guide
Observable in production
- Prometheus metrics endpoint
- health and readiness probes
- webhooks, SSE and WebSocket events
- S3 backups for disaster recovery
Start in under a minute.
One install, ten lines, zero infrastructure. On the runtime you already use.
If bunqueue removes a Redis box from your stack, a star on GitHub helps other teams find it.