Strait Docs
Guides

Move your background jobs from BullMQ to Strait with minimal changes.

Migrating from BullMQ

This guide helps you migrate from BullMQ (Redis-backed Node.js queue) to Strait. The core concepts map closely, but Strait replaces Redis queuing with PostgreSQL-backed orchestration.

Concept Mapping

BullMQStraitNotes
QueueJobA job definition with endpoint, schedule, and retry config
JobRunA single execution of a job
WorkerWorker modestrait server --mode worker
Processor functionHTTP endpointYour job logic lives behind an HTTP endpoint
Repeatable jobsCron scheduleschedule: "*/5 * * * *"
Job attemptsmax_retriesSame concept, configured per job
Backoff strategiesretry_strategyexponential, linear, fixed, or custom
Flow (parent/child)Workflow DAGMore powerful: fan-in/fan-out, conditions, approvals
Rate limiterPer-key rate limitingBuilt into job definitions
Delayed jobsdelayed_secsSchedule runs for the future

Step-by-Step Migration

1. Replace queue definitions with job definitions

BullMQ:

const emailQueue = new Queue("send-email", { connection: redis });

Strait:

strait jobs create --name "send-email" \
  --endpoint "https://your-app.com/api/jobs/send-email" \
  --timeout 60 \
  --max-retries 3 \
  --retry-strategy exponential

2. Convert processors to HTTP endpoints

BullMQ:

const worker = new Worker("send-email", async (job) => {
  await sendEmail(job.data.to, job.data.subject, job.data.body);
}, { connection: redis });

Strait:

export async function POST(req: Request) {
  const { payload } = await req.json();
  await sendEmail(payload.to, payload.subject, payload.body);
  return Response.json({ status: "sent" });
}

3. Replace queue.add() with API triggers

BullMQ:

await emailQueue.add("welcome", { to: "user@example.com", subject: "Welcome" });

Strait:

const client = createClient({ baseUrl: "http://localhost:8080", apiKey: "..." });
await client.jobs.trigger("send-email", {
  payload: { to: "user@example.com", subject: "Welcome" },
});

4. Convert repeatable jobs to cron schedules

BullMQ:

await queue.add("cleanup", {}, { repeat: { cron: "0 0 * * *" } });

Strait:

strait jobs create --name "cleanup" \
  --endpoint "https://your-app.com/api/jobs/cleanup" \
  --schedule "0 0 * * *"

5. Replace Flows with Workflow DAGs

BullMQ:

const flow = new FlowProducer({ connection: redis });
await flow.add({ name: "parent", queueName: "pipeline", children: [...] });

Strait:

{
  "name": "pipeline",
  "steps": [
    { "name": "step-1", "job": "extract" },
    { "name": "step-2", "job": "transform", "depends_on": ["step-1"] },
    { "name": "step-3", "job": "load", "depends_on": ["step-2"] }
  ]
}

What You Gain

  • No Redis dependency -- PostgreSQL handles queuing with SKIP LOCKED
  • Built-in observability -- Logs, metrics, and traces without extra infrastructure
  • Workflow orchestration -- DAGs with conditions, approvals, and event waits
  • Multi-language SDKs -- Your job endpoints can be in any language
  • Cost budgets -- Track and limit AI/API spending per run
Was this page helpful?

On this page