Overview
We need to introduce a robust background task / job queue system using BullMQ.
Currently, background processing is minimal or synchronous. As we scale and add features like email dispatch, heavy computations, third-party integrations, or periodic syncs, we need a reliable, Redis-backed queue system with retries, delay support, and concurrency controls.
The architecture must support:
- Same-server execution (Now): Running the background worker on the same server as the primary Nuxt/Nitro application.
- Separate-server execution (Future): Offloading the background worker to a separate dedicated server/service/container without modifying the application code, simply by pointing it to the same shared Redis instance.
Design & Architecture
1. Separation of Concerns
To make the transition to a separate server seamless in the future, the background worker should run as a separate process rather than inline within the Nuxt/Nitro event loop.
- Producer (Nuxt/Nitro API): imports
Queue from BullMQ, defines jobs, and adds them to Redis.
- Consumer (Worker Process): A standalone script (e.g.,
server/worker.ts or a top-level worker.ts run via Bun) that imports Worker and processes jobs.
2. PM2 Process Configuration (ecosystem.config.js)
We will configure PM2 to run both the API and the Worker as separate applications. This makes it trivial to split them later:
module.exports = {
apps: [
{
name: "api21",
script: ".output/server/index.mjs",
interpreter: "bun",
// ...
},
{
name: "api21-worker",
script: "server/worker.ts", // or compiled equivalent
interpreter: "bun",
instances: 1,
autorestart: true,
watch: false,
env: {
NODE_ENV: "production",
}
}
]
};
Tasks to Complete
Phase 1: Setup and Configuration
Phase 2: Implement the Worker Process
Phase 3: Integration & Local Orchestration
Phase 4: Monitoring (Optional but recommended)
Phase 5: Verification & Tests
Overview
We need to introduce a robust background task / job queue system using BullMQ.
Currently, background processing is minimal or synchronous. As we scale and add features like email dispatch, heavy computations, third-party integrations, or periodic syncs, we need a reliable, Redis-backed queue system with retries, delay support, and concurrency controls.
The architecture must support:
Design & Architecture
1. Separation of Concerns
To make the transition to a separate server seamless in the future, the background worker should run as a separate process rather than inline within the Nuxt/Nitro event loop.
Queuefrom BullMQ, defines jobs, and adds them to Redis.server/worker.tsor a top-levelworker.tsrun via Bun) that importsWorkerand processes jobs.2. PM2 Process Configuration (
ecosystem.config.js)We will configure PM2 to run both the API and the Worker as separate applications. This makes it trivial to split them later:
Tasks to Complete
Phase 1: Setup and Configuration
bullmq) and any necessary Redis client dependencies (typicallyioredisis preferred/used internally by BullMQ).Phase 2: Implement the Worker Process
server/worker.ts(orsrc/worker.ts) to initialize BullMQWorkerinstances.Phase 3: Integration & Local Orchestration
ecosystem.config.jsto run the worker process alongside the Nuxt app.Phase 4: Monitoring (Optional but recommended)
/admin/queuesor as a separate microservice to monitor queue health and retry failed jobs.Phase 5: Verification & Tests