Back to results for “Performance & Optimization”
Node.js › Background Jobs & Queues

How would you track and expose the progress of a long-running background job to the client that requested it?

Intermediate

Answer

The worker processing the job periodically updates a progress value (a percentage, or a count of completed steps) stored somewhere the client can query -- either directly on the job object itself (BullMQ supports job.updateProgress()), or in a separate database/cache record -- and the client polls a status endpoint (or subscribes via WebSocket/Server-Sent Events for real-time updates) to retrieve that current progress value without needing to wait for full completion.
// Worker updates progress as it processes
new Worker('video-encode', async (job) => {
  for (let i = 0; i < totalChunks; i++) {
    await encodeChunk(i);
    await job.updateProgress(Math.round((i / totalChunks) * 100));
  }
});

// Client polls for status
app.get('/jobs/:id/status', async (req, res) => {
  const job = await videoQueue.getJob(req.params.id);
  res.json({ progress: job.progress, state: await job.getState() });
});
Real-world example A video-transcoding platform lets users watch a live progress bar update from 0% to 100% by polling a /jobs/:id/status endpoint every two seconds, backed by the worker calling job.updateProgress() after each processed video chunk.

Common follow-ups: When is Server-Sent Events or WebSockets a better fit than polling for delivering this progress information?;How granular should progress updates be without adding excessive overhead to the job itself?