Retries & backoff
Throw from your handler and NextMQ retries with fixed or exponential backoff. The retry schedule lives on our server, not in a function timeout.
Drop in the same Queue and Worker API you already use. NextMQ hosts the queue server and Redis, auto-manages your webhook endpoint, and handles retries, scheduling, and rate limits by default — so background jobs just work on serverless. No infra to run.
The BullMQ-API-compatible SDK lives in your app and talks to NextMQ over HTTPS. We run the server and Redis for you.
BullMQ needs a process that stays alive and a live Redis connection. Serverless Next.js has neither — so you'd end up running and babysitting infrastructure. NextMQ runs all of it for you.
Install @nextmq/sdk and drop in the project keys from your dashboard. That's the setup.
The same Queue, Worker, and FlowProducer API. Nothing new to learn, nothing to configure.
Your jobs execute on our managed BullMQ and call your code back over a signed webhook — with retries, scheduling, and rate limits built in.
Everything that makes BullMQ hard on serverless lives on our side of the line. You ship features; we keep the queue running.
It's the same Queue, Worker, and FlowProduceryou already write — pointed at a managed server instead of a Redis you operate. Add one route handler and you're done.
import { Queue, Worker } from '@nextmq/sdk'
// A normal BullMQ queue — except it runs on NextMQ's managed server.
// No Redis to provision, no worker process to keep alive.
const media = new Queue<{ uploadId: string }>('media')
export const mediaWorker = new Worker('media', async (job) => {
await job.updateProgress(20)
const { url } = await transcode(job.data.uploadId) // your long task
return { url }
})
// Enqueue from a route or server action.
// Retries, backoff and scheduling are handled for you.
await media.add('transcode', { uploadId }, {
attempts: 5,
backoff: { type: 'exponential', delay: 1000 },
})// app/api/nextmq/[...path]/route.ts — the only wiring you add.
import { createNextMQHandler } from '@nextmq/sdk/next'
import { mediaWorker } from '@/jobs/media'
export const runtime = 'nodejs'
// NextMQ auto-registers your workers and verifies every signed call.
export const { GET, POST } = createNextMQHandler({ workers: [mediaWorker] })Every control that makes BullMQ worth using is on by default — managed on our server, available through the API you already know.
Throw from your handler and NextMQ retries with fixed or exponential backoff. The retry schedule lives on our server, not in a function timeout.
Run a job in ten minutes or every night at 3am. Delayed and repeating jobs fire from our server even while your app is scaled to zero.
Cap calls to a third-party or AI API by time window — enforced on our server, so a traffic spike can't blow through your provider quota.
Decide how many jobs run at once per queue. The real BullMQ scheduler honors it across every invocation of your app.
Fan work into parent/child graphs with FlowProducer and gather child results — the dependencies are tracked for you.
Collapse duplicate jobs with a dedup key, so a double-submitted form or a retried request only runs the work once.
Real BullMQ runs your jobs, so the API you reach for is the API you already know.
A few methods that assume a worker running inside your own process work differently over a managed connection. See the compatibility guide.
Create a project, grab your keys, and enqueue. No server, no Redis, no webhook plumbing — just the BullMQ you already know.