How it works
You write a queue and a processor. NextMQ runs the BullMQ server and Redis, schedules the work, and calls your processor back over a signed webhook.
The SDK lives in your app and talks to NextMQ over HTTPS.
Your side#
@nextmq/sdk gives you the BullMQ-shaped Queue, Worker, and FlowProducer classes. There's no Redis connection in your app. Calling queue.add() sends an authenticated request to NextMQ. A Worker declares the processor function that should run when a job is triggered.
The one piece of plumbing you add is a webhook route built with createNextMQHandler. It verifies every signed request, registers your workers and dispatches incoming jobs.
Our side#
NextMQ runs the real BullMQ Queue and Worker instances against a managed Redis. We own the scheduler, lock handling, retries, backoff, delays, priority, concurrency, and rate limiting. Your jobs and their state are stored durably and isolated to your project.
The lifecycle of a job#
- Enqueue. Your route calls
queue.add(); the SDK sends it to NextMQ, which stores the job. - Schedule. Our BullMQ worker applies delay, priority, and rate limits, then picks the job up when it's due.
- Dispatch. NextMQ signs the job and calls your webhook route.
- Process. The handler verifies the signature and runs your processor function.
- Finalize. We read your response and mark the job
completed,failed(with retries/backoff), or rate-limited.
Why a webhook instead of a local worker#
A BullMQ worker needs a blocking Redis connection and timers that run continuously — which a serverless function, frozen between requests, can't hold. So that loop lives on our side, and your app only needs to be reachable for one request → one result. This is also why a few BullMQ APIs differ here; see Coming from BullMQ.