---
title: "Bunqueue vs BullMQ: Performance Comparison & Feature Differences"
description: "bunqueue vs BullMQ: 1.3x faster push, 3.2x faster bulk. Zero Redis, native MCP for AI agents, SQLite persistence. Full feature comparison."
head:
  - tag: meta
    attrs:
      property: og:image
      content: https://bunqueue.dev/og/benchmarks.png
---

import { Card, CardGrid, Aside } from '@astrojs/starlight/components';

Real benchmark results comparing bunqueue TCP server against BullMQ with Redis on identical workloads.

<Aside type="note">
This is a **fair comparison**: both systems use network connections (bunqueue TCP vs Redis TCP). For embedded mode benchmarks (no network), bunqueue is significantly faster.
</Aside>

## Summary

<CardGrid>
  <Card title="1.3x Faster Push" icon="rocket">
    **54,140 vs 43,261 ops/sec**

    Single job push operations
  </Card>
  <Card title="3.2x Faster Bulk" icon="star">
    **139,200 vs 44,000 ops/sec**

    Bulk push (100 jobs per batch)
  </Card>
  <Card title="1.7x Faster Processing" icon="approve-check">
    **33,052 vs 19,225 ops/sec**

    Job processing throughput
  </Card>
  <Card title="Zero Infrastructure" icon="laptop">
    **No Redis Required**

    Embedded SQLite vs Redis server
  </Card>
</CardGrid>

---

## Throughput Comparison

<div style={{ textAlign: 'center', margin: '2rem 0' }}>
  <img
    src="https://quickchart.io/chart?c={type:'bar',data:{labels:['Push','Bulk Push','Process'],datasets:[{label:'bunqueue',data:[54140,139200,33052],backgroundColor:'rgba(236,72,153,0.85)'},{label:'BullMQ',data:[43261,44000,19225],backgroundColor:'rgba(59,130,246,0.85)'}]},options:{plugins:{title:{display:true,text:'Throughput Comparison (ops/sec)',font:{size:18,weight:'bold'}},legend:{position:'bottom'}},scales:{y:{title:{display:true,text:'Operations/sec'},grid:{color:'rgba(0,0,0,0.1)'}},x:{grid:{display:false}}}}}&width=600&height=400&backgroundColor=white"
    alt="Throughput comparison chart"
    style={{ maxWidth: '600px', width: '100%', borderRadius: '12px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}
  />
</div>

| Operation | bunqueue | BullMQ | Speedup |
|-----------|----------|--------|---------|
| **Push** | 54,140 ops/sec | 43,261 ops/sec | **1.3x faster** |
| **Bulk Push** | 139,200 ops/sec | 44,000 ops/sec | **3.2x faster** |
| **Process** | 33,052 ops/sec | 19,225 ops/sec | **1.7x faster** |

---

## Latency Comparison

<div style={{ textAlign: 'center', margin: '2rem 0' }}>
  <img
    src="https://quickchart.io/chart?c={type:'bar',data:{labels:['Bulk Push p99'],datasets:[{label:'bunqueue',data:[3.26],backgroundColor:'rgba(236,72,153,0.85)'},{label:'BullMQ',data:[4.53],backgroundColor:'rgba(59,130,246,0.85)'}]},options:{plugins:{title:{display:true,text:'p99 Latency Comparison (ms)',font:{size:18,weight:'bold'}},legend:{position:'bottom'}},scales:{y:{title:{display:true,text:'Latency in ms'},grid:{color:'rgba(0,0,0,0.1)'}},x:{grid:{display:false}}}}}&width=500&height=350&backgroundColor=white"
    alt="Latency comparison chart"
    style={{ maxWidth: '500px', width: '100%', borderRadius: '12px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}
  />
</div>

| Operation | bunqueue p99 | BullMQ p99 | Improvement |
|-----------|--------------|------------|-------------|
| **Bulk Push** | 3.26ms | 4.53ms | **1.4x lower** |

---

## Speedup by Operation

<div style={{ textAlign: 'center', margin: '2rem 0' }}>
  <img
    src="https://quickchart.io/chart?c={type:'bar',data:{labels:['Bulk Push','Process','Push'],datasets:[{label:'bunqueue speedup vs BullMQ',data:[3.2,1.7,1.3],backgroundColor:['rgba(236,72,153,0.85)','rgba(168,85,247,0.85)','rgba(34,197,94,0.85)'],borderRadius:8}]},options:{indexAxis:'y',plugins:{title:{display:true,text:'How Many Times Faster is bunqueue?',font:{size:18,weight:'bold'}},legend:{display:false}},scales:{x:{title:{display:true,text:'Speedup (x times faster)'},grid:{color:'rgba(0,0,0,0.1)'},beginAtZero:true},y:{grid:{display:false}}}}}&width=600&height=250&backgroundColor=white"
    alt="Speedup comparison chart"
    style={{ maxWidth: '600px', width: '100%', borderRadius: '12px', boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1)' }}
  />
</div>

---

## How the Benchmark Works

The benchmark performs three tests for both bunqueue and BullMQ:

### 1. Push Test
Pushes 10,000 jobs using 32 parallel connections to measure raw push throughput.

```typescript
// 32 concurrent clients pushing jobs
await benchmarkParallel('Push', async () => {
  await queue.add('job', PAYLOAD);
}, 10000, 32);
```

### 2. Bulk Push Test
Pushes 100 jobs per batch, 1,000 times (100,000 total jobs) to measure bulk insertion performance.

```typescript
// Batch of 100 jobs per operation
const jobs = Array.from({ length: 100 }, (_, i) => ({
  name: 'bulk-job',
  data: { ...PAYLOAD, i },
}));
await queue.addBulk(jobs);
```

### 3. Process Test
Measures end-to-end throughput: pushing 10,000 jobs and processing them with 50 concurrent workers.

```typescript
// Push jobs in parallel batches
for (let i = 0; i < 10000; i += 1000) {
  await Promise.all(batch.map(() => queue.add('job', PAYLOAD)));
}

// Wait for all to be processed
while (processed < 10000) {
  await new Promise(r => setTimeout(r, 10));
}
```

<Aside type="tip">
Both bunqueue and BullMQ use **identical test conditions**: same payload size (100 bytes), same batch sizes, same concurrency (50 workers), and same parallel push strategy.
</Aside>

---

## Why is bunqueue Faster?

<CardGrid>
  <Card title="TCP Pipelining" icon="rocket">
    bunqueue's TCP protocol supports **pipelining** - multiple commands in flight per connection, with reqId-based response matching.
  </Card>
  <Card title="Optimized Data Structures" icon="list-format">
    Skip lists, MinHeap, and LRU cache provide O(log n) or O(1) operations for common tasks.
  </Card>
  <Card title="Batch Transactions" icon="document">
    SQLite transactions batch multiple operations into single disk writes with WAL mode.
  </Card>
  <Card title="Auto-Scaled Sharding" icon="setting">
    Lock contention is minimized by distributing work across N independent shards (auto-detected from CPU cores, max 64).
  </Card>
</CardGrid>

---

## Feature Comparison

| Feature | bunqueue | BullMQ |
|---------|----------|--------|
| **Queue Types** | ✅ Standard, Priority, LIFO | ✅ Standard, Priority, LIFO |
| **Delayed Jobs** | ✅ Yes | ✅ Yes |
| **Retries & Backoff** | ✅ Exponential | ✅ Exponential |
| **Dead Letter Queue** | ✅ Built-in | ✅ Built-in |
| **Rate Limiting** | ✅ Per-queue | ✅ Per-queue |
| **Cron Jobs** | ✅ Built-in | ✅ Via scheduler |
| **Job Dependencies** | ✅ Parent-child flows | ✅ Parent-child flows |
| **Persistence** | ✅ SQLite (embedded) | ✅ Redis |
| **Horizontal Scaling** | ⚠️ Single process | ✅ Multi-process |
| **External Dependencies** | ✅ None | ❌ Redis required |
| **S3 Backup** | ✅ Built-in | ❌ Manual |
| **TCP Pipelining** | ✅ Built-in | ✅ Via Redis |
| **MCP Server (AI Agents)** | ✅ 73 tools built-in | ❌ Not available |

---

## Run the Benchmark Yourself

The benchmark source code is available at [`bench/comparison/run.ts`](https://github.com/egeominotti/bunqueue/blob/main/bench/comparison/run.ts).

```bash
# Clone the repository
git clone https://github.com/egeominotti/bunqueue.git
cd bunqueue
bun install

# Start Redis (required for BullMQ)
redis-server --daemonize yes

# Start bunqueue server
bun run start &

# Run the benchmark
bun run bench/comparison/run.ts
```

### Benchmark Output

```
═══════════════════════════════════════════════════════════════
           bunqueue vs BullMQ Comparison Benchmark
═══════════════════════════════════════════════════════════════

Iterations: 10,000
Bulk size: 100
Concurrency: 50
Payload: 111 bytes

✓ Redis connected
✓ bunqueue server connected (port 6789)

📦 bunqueue (TCP mode) benchmarks...

  Push: 54,140 ops/sec
  Bulk Push: 139,200 ops/sec (p99: 3.26ms)
  Process: 33,052 ops/sec

🐂 BullMQ (Redis) benchmarks...

  Push: 43,261 ops/sec
  Bulk Push: 44,000 ops/sec (p99: 4.53ms)
  Process: 19,225 ops/sec

═══════════════════════════════════════════════════════════════
                         RESULTS
═══════════════════════════════════════════════════════════════

┌─────────────┬──────────────────┬──────────────────┬──────────┐
│ Operation   │ bunqueue         │ BullMQ           │ Speedup  │
├─────────────┼──────────────────┼──────────────────┼──────────┤
│ Push        │ 54,140 ops/s     │ 43,261 ops/s     │ 1.3x     │
│ Bulk Push   │ 139,200 ops/s    │ 44,000 ops/s     │ 3.2x     │
│ Process     │ 33,052 ops/s     │ 19,225 ops/s     │ 1.7x     │
└─────────────┴──────────────────┴──────────────────┴──────────┘
```

---

## Benchmark Environment

**Hardware:**
- Mac Studio, Apple M1 Max
- 32GB RAM
- SSD storage

**Software:**
- macOS Tahoe
- Bun 1.3.8
- Redis 7.x (localhost)

**Configuration:**
- 10,000 iterations per test
- Bulk size: 100 jobs
- Concurrency: 50 workers
- Payload: ~100 bytes per job
- TCP pipelining enabled
- Connection pool: 32 connections

---

## When to Use BullMQ Instead

While bunqueue is faster for most use cases, BullMQ may be better when:

- **Horizontal scaling** is required across multiple processes/servers
- **Redis** is already part of your infrastructure
- **Redis-specific features** like pub/sub or Lua scripts are needed
- **Multi-language** workers need to share the same queue

<Aside>
For single-process applications, microservices, or edge deployments, bunqueue provides superior performance with simpler operations.
</Aside>
