Part of series: System Design Roadmap
Week 5 Day 5: Mini Project - Job Queue with BullMQ
We will build an Email Sending System. Since SMTP servers are slow, we will offload the sending to a Background Worker.
Requirements
- Redis Installed.
bullmqlibrary.
1. Setup
npm install express bullmq ioredis
2. The Producer (producer.js)
This is the API server.
const express = require('express');
const { Queue } = require('bullmq');
const app = express();
app.use(express.json());
// Connection to Redis
const connection = { host: '127.0.0.1', port: 6379 };
// Create Queue
const emailQueue = new Queue('email-queue', { connection });
app.post('/send-email', async (req, res) => {
const { to, subject, body } = req.body;
// Add Job to Queue
await emailQueue.add('send-email-job', { to, subject, body });
res.json({ status: 'Queued', message: 'Email will be sent shortly.' });
});
app.listen(3000, () => console.log('API running on 3000'));
3. The Worker (worker.js)
This runs in the background.
const { Worker } = require('bullmq');
const connection = { host: '127.0.0.1', port: 6379 };
// Simulate sending email (2 seconds delay)
const sendEmail = async (job) => {
console.log(`Processing Job ${job.id}: Sending email to ${job.data.to}...`);
await new Promise(r => setTimeout(r, 2000));
console.log(`Job ${job.id} Done! Email Sent.`);
};
const worker = new Worker('email-queue', async (job) => {
await sendEmail(job);
}, { connection });
console.log('Worker listening for jobs...');
4. Run it
- Start Redis.
- Run
node worker.js(Worker acts as consumer). - Run
node producer.js. - POST a request.
- API returns “Queued” instantly (10ms).
- Worker logs “Processing…” and finishes 2s later.
Congratulations! You decoupled your API from the heavy task. 🦅 Next week: Microservices. Breaking the Monolith! 🔨