NextMQ

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/sdk

3. Add your keys#

Paste the values from your dashboard into your environment.

.env.local
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.com

NEXTMQ_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.

lib/nextmq.ts
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.

jobs/images.ts
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.

app/api/nextmq/[...path]/route.ts
import { createNextMQHandler } from '@nextmq/sdk/next'
import { imageWorker } from '@/jobs/images'

export const runtime = 'nodejs'

export const { GET, POST } = createNextMQHandler({
  workers: [imageWorker],
})
Note
The route's public URL must sit under 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:

app/api/upload/route.ts
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#