From self-hosted BullMQ to BullRun in 15 minutes
Already running BullMQ? BullRun wraps the same library you already use. Your job definitions work with minimal changes.
What changes
| Before (self-hosted) | After (BullRun) |
|---|---|
| Manage your own Redis | Managed by BullRun |
| Write worker bootstrap code | startWorkers() handles it |
| Build your own dashboard | Included free |
| DIY alerting | Built-in Slack/webhook alerts |
| Job handler code | No change |
Step 1: Install
npm install @bullrun/sdk npm uninstall ioredis # optional: no longer needed
Step 2: Convert your workers
Before:
// worker.ts — self-hosted BullMQ
import { Worker } from "bullmq";
import Redis from "ioredis";
const connection = new Redis(process.env.REDIS_URL);
const worker = new Worker("emails", async (job) => {
await sendEmail(job.data.to, job.data.subject, job.data.body);
}, { connection, concurrency: 10 });After:
// tasks/send-email.ts — BullRun
import { defineTask } from "@bullrun/sdk";
export const sendEmail = defineTask({
name: "send-email",
queue: "emails",
concurrency: 10,
handler: async (payload: { to: string; subject: string; body: string }) => {
await sendEmail(payload.to, payload.subject, payload.body);
},
});The handler code is identical. You just wrap it in defineTask() and remove the Redis/Worker boilerplate.
Step 3: Convert your producers
Before:
const queue = new Queue("emails", { connection });
await queue.add("send-email", { to: "user@example.com", subject: "Hi" });After:
const client = new BullRun({ apiKey: "br_..." });
await client.trigger("send-email", { to: "user@example.com", subject: "Hi" });Step 4: Deploy
npx bullrun deploy
That's it. Your Redis is now managed, your dashboard is live, and alerts fire when things break.