FAQ
General
What is bunqueue?
bunqueue is a high-performance job queue for Bun that uses SQLite for persistence instead of Redis. It provides a BullMQ-compatible API, making migration easy.
Why SQLite instead of Redis?
- Simplicity: No external service to manage
- Performance: Bun’s native SQLite is incredibly fast
- Persistence: Data survives restarts by default
- Cost: No Redis hosting costs
- Portability: Single file database, easy to backup
Is bunqueue production-ready?
Yes. bunqueue includes:
- Stall detection for crashed workers
- Dead letter queues for failed jobs
- Automatic retries with backoff
- S3 backups for disaster recovery
- Rate limiting and concurrency control
What are the system requirements?
- Bun: Version 1.0 or higher
- OS: macOS, Linux, Windows (WSL)
- Memory: Minimum 512MB recommended
- Disk: SSD recommended for best performance
Installation
Why doesn’t it work with Node.js?
bunqueue uses Bun-specific APIs:
bun:sqlitefor database accessBun.servefor HTTP serverBun.listenfor TCP server
These APIs are not available in Node.js.
How do I install Bun?
# macOS/Linuxcurl -fsSL https://bun.sh/install | bash
# Windows (PowerShell)powershell -c "irm bun.sh/install.ps1 | iex"
# Homebrewbrew install oven-sh/bun/bunArchitecture
What’s the difference between embedded and server mode?
Embedded Mode:
- Queue runs in the same process as your app
- Best for single-process applications
- No network overhead
Server Mode:
- Queue runs as a separate server
- Multiple workers can connect via TCP
- Best for distributed systems
Can I use both modes together?
No. Each mode uses its own database file. You should choose one mode per deployment.
How does job persistence work?
Jobs are stored in SQLite with WAL (Write-Ahead Logging) mode:
- Writes are fast and atomic
- Reads don’t block writes
- Data survives process crashes
- Automatic checkpointing
Performance
How many jobs can bunqueue handle?
On typical hardware (M2 Pro, 16GB RAM):
- Push: 125,000 jobs/second
- Pull: 100,000 jobs/second
- Latency: 0.1-0.5ms p99
How do I optimize throughput?
-
Increase concurrency
const worker = new Worker('queue', processor, {concurrency: 50}); -
Use batch operations
await queue.addBulk(jobs);await queue.ackBatch(jobIds); -
Enable WAL mode (default)
Terminal window sqlite3 queue.db "PRAGMA journal_mode=WAL;"
Why are my jobs slow?
Common causes:
- Low concurrency setting
- Slow job processor function
- Database on HDD instead of SSD
- Too many indexes
Job Processing
What happens if a worker crashes?
With stall detection enabled:
- Worker misses heartbeat
- Job is marked as stalled
- Job is retried automatically
- If max stalls exceeded, sent to DLQ
How do retries work?
await queue.add('task', data, { attempts: 5, // Max attempts backoff: 1000 // Base delay in ms (doubles each retry)});Retry delays: 1s → 2s → 4s → 8s → 16s
What is the Dead Letter Queue?
The DLQ stores jobs that:
- Exceeded max retry attempts
- Had unrecoverable errors
- Exceeded max stalls
You can inspect, retry, or purge DLQ jobs.
Can I process jobs in order?
Yes, use LIFO mode:
await queue.add('task', data, { lifo: true });Or use priority:
await queue.add('high', data, { priority: 10 });await queue.add('low', data, { priority: 1 });Scaling
Can I run multiple workers?
Yes. In server mode, multiple workers can connect:
// Worker 1const worker1 = new Worker('queue', processor);
// Worker 2 (different process/machine)const worker2 = new Worker('queue', processor);Does bunqueue support clustering?
Not built-in. For high availability:
- Use S3 backups for failover
- Run read replicas with SQLite replication
- Use load balancer for multiple servers
How do I handle high load?
- Horizontal scaling: Add more workers
- Rate limiting: Protect downstream services
- Priority queues: Process important jobs first
- Batch processing: Reduce overhead
Data & Backup
Where is data stored?
Default: ./data/bunq.db
Configure with:
DATA_PATH=./data/production.db bunqueue startHow do I backup the database?
Option 1: S3 Automatic Backup
S3_BACKUP_ENABLED=1 \S3_BUCKET=my-bucket \S3_ACCESS_KEY_ID=xxx \S3_SECRET_ACCESS_KEY=xxx \bunqueue startOption 2: Manual Backup
sqlite3 queue.db ".backup backup.db"How do I restore from backup?
bunqueue backup listbunqueue backup restore backups/2024-01-15/queue.db --forceTroubleshooting
”SQLITE_BUSY: database is locked”
Multiple writers are conflicting. Solutions:
- Use server mode for multi-process
- Ensure only one embedded instance
- Check for stale lock files
”Job not found”
The job was already:
- Completed and removed (
removeOnComplete: true) - Failed and removed (
removeOnFail: true) - Manually deleted
High memory usage
Common causes:
- Too many jobs in memory
- DLQ accumulating failed jobs
- Job data is too large
Solutions:
// Remove completed jobsawait queue.add('task', data, { removeOnComplete: true });
// Purge old DLQ entriesqueue.purgeDlq();
// Clean old jobsqueue.clean(3600000); // 1 hourMigration
Can I migrate from BullMQ?
Yes. See the Migration Guide.
Key differences:
- No Redis connection needed
- Backoff is simplified
- Rate limiting is on queue, not worker
Can I migrate from other queues?
bunqueue uses a standard job format. Export your jobs as JSON and use:
const jobs = loadJobsFromOldQueue();await queue.addBulk(jobs.map(j => ({ name: j.type, data: j.payload, opts: { priority: j.priority }})));Contributing
How can I contribute?
- Report bugs on GitHub Issues
- Submit PRs for bug fixes
- Propose features in Discussions
- Improve documentation
What’s the development setup?
git clone https://github.com/egeominotti/bunqueuecd bunqueuebun installbun testbun run dev