Quickstart
From zero to a working background job in a Next.js app. There's no server or Redis to set up — that's the part we manage.
1. Create a project#
Sign up and create a project in the NextMQ dashboard. You'll get a server URL, an API key, an admin key, and a webhook secret. Keep them handy for the next step.
2. Install the SDK#
npm install @nextmq/sdk3. Add your keys#
Paste the values from your dashboard into your environment.
NEXTMQ_SERVER_URL=https://api.nextmq.com
NEXTMQ_API_KEY=app_xxx
NEXTMQ_ADMIN_API_KEY=admin_xxx
NEXTMQ_WEBHOOK_SECRET=whsec_xxx
NEXTMQ_WEBHOOK_BASE_URL=https://your-app.comNEXTMQ_WEBHOOK_BASE_URLis your app's public URL — it's where NextMQ calls back to run your jobs. Use http://localhost:3000 with a tunnel locally, or your deployed domain in production.
4. Configure the SDK#
Call configureNextMQ once, in a module your producers and route both import.
import { configureNextMQ } from '@nextmq/sdk'
configureNextMQ({
serverUrl: process.env.NEXTMQ_SERVER_URL!,
apiKey: process.env.NEXTMQ_API_KEY!,
adminKey: process.env.NEXTMQ_ADMIN_API_KEY,
webhookSecret: process.env.NEXTMQ_WEBHOOK_SECRET!,
webhookBaseUrl: process.env.NEXTMQ_WEBHOOK_BASE_URL!,
})5. Define a queue and a worker#
The same primitives as BullMQ. The processor is the code NextMQ calls back to run.
import '@/lib/nextmq'
import { Queue, Worker } from '@nextmq/sdk'
export const images = new Queue<{ uploadId: string }>('images')
export const imageWorker = new Worker('images', async (job) => {
await job.updateProgress(25)
const thumb = await makeThumbnail(job.data.uploadId)
return { thumbnailUrl: thumb.url }
})6. Add the webhook route#
One catch-all route handles every queue. It verifies signatures, dispatches jobs to the right worker, and exposes a /health path. It must run on the Node.js runtime.
import { createNextMQHandler } from '@nextmq/sdk/next'
import { imageWorker } from '@/jobs/images'
export const runtime = 'nodejs'
export const { GET, POST } = createNextMQHandler({
workers: [imageWorker],
})NEXTMQ_WEBHOOK_BASE_URL — here NextMQ calls back to https://your-app.com/api/nextmq/….7. Enqueue a job#
From a route handler or server action:
import { images } from '@/jobs/images'
export async function POST(req: Request) {
const { uploadId } = await req.json()
await images.add('thumbnail', { uploadId }, {
attempts: 5,
backoff: { type: 'exponential', delay: 1000 },
})
return Response.json({ queued: true })
}What happens now#
NextMQ stores the job, a real BullMQ worker picks it up, and it calls your /api/nextmq route to run imageWorker. If your processor throws, NextMQ retries with exponential backoff up to five attempts — no extra code from you.
Keep going#
- Queues & job options — every supported
add()option. - Workers & processing — concurrency, rate limits, and outcomes.
- Deploying to Vercel — env vars and keeping idle queues warm.