The queue, from the CLI.
One binary, two roles: bunqueue start runs the server, every other command talks to a running one. Push, pull, ack, DLQ, cron, backups, and monitoring, all scriptable with JSON output.
Start the Server
Section titled “Start the Server”bunqueue start # defaults: TCP 6789, HTTP 6790bunqueue start --tcp-port 7000 --http-port 7001 # custom portsbunqueue start --host 127.0.0.1 -p 6789 # bind to a specific hostbunqueue start --data-path ./data/production.db # persistent storageAUTH_TOKENS=secret-token bunqueue start # with authenticationbunqueue start --config ./bunqueue.config.ts # with a config fileOn startup the server prints its ports, data path, and enabled features (TLS, auth, S3 backup, cloud, shard count).
Connect to a Server
Section titled “Connect to a Server”Client commands default to localhost:6789:
bunqueue stats # local serverbunqueue stats --host 192.168.1.100 --port 6789 # remote serverbunqueue stats --token secret-token # with authenticationSet the token once via environment variable instead of repeating the flag. Priority: --token flag > BQ_TOKEN > BUNQUEUE_TOKEN.
export BQ_TOKEN=my-secret-tokenPush, Pull, Ack, Fail
Section titled “Push, Pull, Ack, Fail”The core loop: add a job, take it, and report the outcome.
bunqueue push emails '{"to":"user@example.com","subject":"Welcome"}'# Job created: 019ce9d7-6983-7000-946f-48737be2b0f9Job IDs are UUID v7 strings (time-ordered). Push accepts options for priority, retries, deduplication, and more:
bunqueue push emails '{"to":"vip@example.com"}' --priority 10 # higher = soonerbunqueue push notifications '{"msg":"hi"}' --delay 5000 # run in 5sbunqueue push orders '{"orderId":"ORD-123"}' --job-id order-ORD-123 # idempotent IDbunqueue push emails '{"to":"a@b.c"}' --max-attempts 5 --backoff 2000 # retry configbunqueue push notifications '{"userId":"1"}' -u user-1-notify # unique key (dedup)bunqueue push aggregate '{"type":"sum"}' --depends-on job-1,job-2 # wait for other jobs| Option | Short | Default | Description |
|---|---|---|---|
--priority | -P | 0 | Higher = processed first |
--delay | -d | 0 | Delay in ms before processing |
--job-id | - | - | Custom ID for deduplication |
--max-attempts | - | 3 | Max retry attempts |
--backoff | - | 1000 | Delay between retries (ms) |
--ttl | - | - | Time-to-live in ms |
--timeout | - | - | Processing timeout in ms |
--unique-key | -u | - | Deduplication key |
--depends-on | - | - | Comma-separated job IDs to wait for |
--tags | - | - | Comma-separated tags |
--group-id | -g | - | Group identifier |
--lifo | - | false | Last in, first out ordering |
--remove-on-complete | - | false | Auto-delete on completion |
--remove-on-fail | - | false | Auto-delete on failure |
Pull the next job (typically a worker’s job, but handy for debugging):
bunqueue pull emails # prints the job, or "No job available"bunqueue pull emails --timeout 5000 # wait up to 5s for a jobThen acknowledge (mark done) or fail it:
bunqueue ack 019ce9d7-... --result '{"delivered":true}' # result retrievable laterbunqueue fail 019ce9d7-... --error "SMTP connection timeout"A failed job is retried with backoff while attempts remain, then moved to the DLQ.
Inspect and Control Jobs
Section titled “Inspect and Control Jobs”bunqueue job get <id> # full details (use --json for the raw object)bunqueue job state <id> # just the statebunqueue job result <id> # the stored resultbunqueue job logs <id> # log entries attached to the job
bunqueue job cancel <id> # cancel a waiting/delayed jobbunqueue job promote <id> # run a delayed job nowbunqueue job discard <id> # send a job to the DLQ
bunqueue job progress <id> 50 --message "Halfway" # update progress (active jobs)bunqueue job update <id> '{"to":"new@example.com"}' # replace job databunqueue job priority <id> 20 # change prioritybunqueue job delay <id> 60000 # move an active job back to delayedbunqueue job wait <id> --timeout 30000 # block until completed, print resultbunqueue job log <id> "Checkpoint reached" --level info # append a log entryCommands print OK on success, or Error: Job not found ... with exit code 1. job wait exits 1 if the job does not complete within the timeout.
Queue Control
Section titled “Queue Control”bunqueue queue list # list all queuesbunqueue queue count emails # total jobs in a queuebunqueue queue pause emails # workers stop picking new jobsbunqueue queue resume emailsbunqueue queue paused emails # prints "Queue is paused" or "Queue is active"
bunqueue queue jobs emails --state waiting --limit 10 # list jobs by state# states: waiting, delayed, active, completed, failed (--offset for pagination)
bunqueue queue clean emails --grace 3600000 --state completed # remove old jobs# default state when omitted: waiting/delayed; --limit caps per call (default 1000)
bunqueue queue drain emails # remove all waiting jobs (active ones keep running)bunqueue queue obliterate emails # remove EVERYTHING for this queueInspect and recover permanently failed jobs (see Dead Letter Queue):
bunqueue dlq list emails # entries with error and timestamp (--count 10)bunqueue dlq retry emails # re-queue all, prints the count movedbunqueue dlq retry emails --id <job-id> # re-queue onebunqueue dlq purge emails # delete all entries, prints the countSchedule recurring jobs (see Cron Jobs):
# Cron expression: daily at 6 AM (optionally --timezone/-z Europe/Rome)bunqueue cron add daily-report -q reports -d '{"type":"daily"}' -s "0 6 * * *"# Cron scheduled: daily-report (next run: 2024-01-16T06:00:00.000Z)
# Plain interval: every 30 minutesbunqueue cron add health-check -q health -d '{"check":"all"}' -e 1800000
bunqueue cron list # name, queue, schedule, executions, next runbunqueue cron delete daily-reportRate and Concurrency Limits
Section titled “Rate and Concurrency Limits”bunqueue rate-limit set emails 100 # max 100 jobs/secondbunqueue concurrency set emails 10 # max 10 concurrent jobsbunqueue rate-limit clear emailsbunqueue concurrency clear emailsMonitoring
Section titled “Monitoring”bunqueue ping # quickest TCP liveness check (works, though not listed in --help)bunqueue stats # waiting/active/delayed/completed/failed/DLQ counts, uptime, ratesbunqueue metrics # Prometheus text format, same as GET /prometheusbunqueue health # alias of stats over TCPbunqueue version # client + server version, warns on mismatchFor a JSON health payload (status, version, memory, connections), use the HTTP endpoint: curl http://localhost:6790/health.
bunqueue doctor runs a full diagnostic: client and server version, reachability, health status, uptime, connections, queue counts, and memory. It prints a check-by-check report and All checks passed. when healthy. Use --host/--port to check a remote server.
Workers and Webhooks
Section titled “Workers and Webhooks”bunqueue worker list # registered workers with statusbunqueue worker register email-worker -q emails,notificationsbunqueue worker unregister w-abc123bunqueue webhook listbunqueue webhook add https://example.com/hooks -e job.completed,job.failed -q emails# Webhook added: <id> (keep the ID for webhook remove)bunqueue webhook remove <id>--events (-e) is required; valid events are job.pushed, job.started, job.completed, job.failed, job.progress. Optional: --queue/-q filter and --secret/-s HMAC secret. See Webhooks.
Backups
Section titled “Backups”Backup commands run locally, not through the TCP server: they require a
persistent database path from BUNQUEUE_DATA_PATH (or its aliases) and read
credentials from the S3_* environment variables, including temporary
S3_SESSION_TOKEN credentials when used (see S3 Backup).
bunqueue backup now # create a backup, prints key/size/durationbunqueue backup list # list backups in the bucketbunqueue backup status # show configurationbunqueue backup restore <key> -f # restore; requires --force, stop the server firstStopping is mandatory for restore. The command validates a temporary candidate and quarantines stale SQLite WAL/SHM sidecars, but it cannot invalidate a database handle held by a running server.
Global Options
Section titled “Global Options”| Option | Short | Description | Default |
|---|---|---|---|
--host | -H | Server hostname | localhost |
--port | -p | TCP port | 6789 |
--token | -t | Authentication token (env: BQ_TOKEN, BUNQUEUE_TOKEN) | - |
--tls | - | Connect with TLS (verify with system CAs) | false |
--tls-ca <file> | - | Trust a custom CA cert (implies --tls) | - |
--tls-no-verify | - | TLS without cert verification (self-signed, dev only) | false |
--json | - | Output as JSON | false |
--help | - | Show help | - |
--version | - | Show version | - |
Scripting with JSON
Section titled “Scripting with JSON”Every command supports --json. It prints the raw server response ({ "ok": true, ... }), so nest your jq path under the response field (.stats, .jobs, .job, .counts, …):
bunqueue stats --json | jq '.stats.waiting'# 234Process a job manually:
JOB=$(bunqueue pull emails --json) # { "ok": true, "job": { ... } }JOB_ID=$(echo $JOB | jq -r '.job.id')echo "Processing job $JOB_ID..." # your logic herebunqueue ack $JOB_ID --result '{"processed":true}'Daily maintenance script:
#!/bin/bashbunqueue queue clean emails --grace 86400000 --state completedbunqueue dlq purge emailsbunqueue backup now