DEV Community

Cover image for No Redis Required: Zero-Config Job Queue for Bun
Egeo Minotti
Egeo Minotti

Posted on

No Redis Required: Zero-Config Job Queue for Bun

I stopped configuring Redis. Here's what I use instead.

The Setup

import { Queue, Worker } from 'bunqueue/client';

const queue = new Queue('tasks', { embedded: true });

await queue.add('process', { userId: 123 });

new Worker('tasks', async (job) => {
  return { done: true };
}, { embedded: true });
Enter fullscreen mode Exit fullscreen mode

That's the entire infrastructure. No Redis. No Docker. No connection strings. No server process.

What embedded: true Actually Does

When you set embedded: true, bunqueue creates a SQLite database in your project and manages everything in-process:

Your App Process
├── Your Code
├── Queue (in-memory priority queues)
├── Worker (processes jobs)
└── SQLite (./data/bunq.db)
Enter fullscreen mode Exit fullscreen mode

One process. One file. Done.

Real Example: Background Email Processing

import { Queue, Worker } from 'bunqueue/client';

interface EmailJob {
  to: string;
  template: string;
  data: Record<string, unknown>;
}

const emails = new Queue<EmailJob>('emails', { embedded: true });

// Add jobs from your API routes
await emails.add('welcome', {
  to: 'user@example.com',  template: 'welcome',
  data: { name: 'John' }
}, {
  attempts: 3,
  backoff: 5000,
  priority: 10
});

// Process in the same app
const worker = new Worker<EmailJob>('emails', async (job) => {
  await job.updateProgress(10, 'Loading template');

  const html = await renderTemplate(job.data.template, job.data.data);

  await job.updateProgress(50, 'Sending');
  await sendEmail(job.data.to, html);

  return { sent: true };
}, {
  embedded: true,
  concurrency: 5
});

worker.on('failed', (job, err) => {
  console.error(`Email to ${job.data.to} failed: ${err.message}`);
});
Enter fullscreen mode Exit fullscreen mode

Install

bun add bunqueue
Enter fullscreen mode Exit fullscreen mode

Top comments (0)