← All projects
Distributed Systems· Production & Systems· Built· Mar 2026

ConquerManage

A small job queue. An Express producer pushes tasks into Redis, and a pool of workers picks them up, retries failures, and dead-letters the ones that keep failing.

Terminal: health checks and enqueue requests against the producer
Enqueueing tasks against the running stack.

Overview

I first wrote this in Go, then rewrote it in TypeScript to understand how the same producer/worker pattern works on Node's event loop. The producer takes POST /enqueue, validates the task and puts it in a Redis list. The worker service runs several loops that pull tasks and process them. The task handlers (send_email, resize_image, generate_pdf) just log what they would do. The point was the queue, not the jobs.

Problem

Slow work like sending emails shouldn't block an HTTP request. It should go to the background, and if it fails it shouldn't just vanish.

Approach

Tasks get a UUID and are RPUSHed onto a list. Workers BLPOP them, so there's no busy polling. A failed task goes back on the queue with one fewer retry, and once it's out of retries it goes to a dead-letter list where I can inspect it later.

Architecture / how it works

  • Each worker loop gets its own Redis connection. A blocking BLPOP holds its connection while it waits, so loops sharing one client would just take turns.
  • BLPOP blocks for at most 5s, then loops. There's no polling burning CPU, and a worker notices a shutdown within 5 seconds.
  • Concurrency comes from WORKER_CONCURRENCY (default 3): N async loops started together.
  • Failed tasks go back on the queue with retries - 1. At zero they're pushed to task_queue:dead.
  • On SIGINT or SIGTERM it stops taking new work, lets in-flight tasks finish, then closes Redis, with an 8s cap so it finishes before Docker's 10s kill.
  • Validation per task type, e.g. send_email needs to and subject.
  • Docker Compose runs redis, the producer (:3000) and the worker (:3001, with /health and /metrics).

Tech stack

TypeScriptNode.jsExpressRedisioredisDocker Compose

Outcomes

It runs end to end with Docker Compose (the gallery has a full run). The thing I didn't expect: BLPOP holds its connection while it waits, so real parallelism needs one Redis connection per worker loop.

Gallery

Terminal session: compose up, health checks, enqueue, validation error, metrics, compose down
A full run: compose up, health checks, a few tasks, one rejected by validation, then the worker's metrics.
Terminal: docker compose up --build output
Building the producer and worker images.

Resume

Want my resume?

I share it on request, so you always get the latest version. Drop me an email with a line about the role or why you're asking, and I'll send it over.

devanshpandeyji4321@gmail.com
Write the email →