A robust, scalable background job processing system built with Node.js, Express, PostgreSQL, and Redis.
- REST API for submitting jobs
- Redis-based queue for reliable job distribution
- Multiple worker support (horizontal scaling)
- Automatic retry logic with configurable max attempts
- Dead Letter Table (DLT) for failed jobs
- Heartbeat monitoring to detect stuck jobs
- Reaper service that automatically recovers stale and orphaned jobs
- Persistent job storage in PostgreSQL
API Layer (Express)
↓
Job Details → PostgreSQL
↓
Queue (Redis List: "queue:pending")
↓
Worker(s) → Process Job → Update Status
↓
Reaper (every 30s) → Recovers stale jobs
- Runtime: Node.js
- Framework: Express.js
- Database: PostgreSQL
- Queue: Redis
├── app.js # Main Express server
├── worker.js # Background job processor
├── reaper.js # Stale job recovery service
├── controllers/
│ └── job.controllers.js # Job creation logic
├── routes/
│ └── job.routes.js # API routes
├── utils/
│ ├── database.utils.js # PostgreSQL pool
│ └── redis.utils.js # Redis client
├── package.json
├── .env.example
└── README.md
- Node.js (v18 or higher)
- PostgreSQL
- Redis
-
Clone the repository
git clone https://github.com/renuthomas/Job-Processing-System.git cd Job-Processing-System -
Install dependencies
npm install
-
Environment Setup
cp .env.example .env
Edit the
.envfile with your credentials. -
Database Setup
Create a database named
joband execute the following SQL:CREATE TABLE job_details ( id BIGSERIAL PRIMARY KEY, type VARCHAR(100) NOT NULL, payload JSONB NOT NULL, status VARCHAR(20) DEFAULT 'pending', attempts INTEGER DEFAULT 0, max_attempts INTEGER DEFAULT 3, created_at TIMESTAMP DEFAULT NOW(), started_at TIMESTAMP, completed_at TIMESTAMP, heartbeat_at TIMESTAMP ); CREATE TABLE dlq ( id BIGSERIAL PRIMARY KEY, job_id BIGINT NOT NULL REFERENCES job_details(id), type VARCHAR(100), payload JSONB, attempts INTEGER, error TEXT, created_at TIMESTAMP DEFAULT NOW() );
Terminal 1 - API Server
npm startTerminal 2 - Worker
npm run workerTerminal 3 - Reaper
npm run reaperPOST /api/jobs
Request:
{
"type": "email.send",
"payload": {
"to": "user@example.com",
"subject": "Welcome",
"body": "Hello there!"
}
}Response:
{
"message": "Job created successfully",
"jobId": 42
}- Workers log job processing and errors
- Reaper logs recovered jobs
- Check
job_detailstable for status (pending,active,completed,failed) - Failed jobs with max attempts are moved to the
dlqtable
- Delayed & scheduled jobs
- Job priorities
- Admin dashboard
- Docker & Docker Compose setup
- Unit & integration tests
- Better rate limiting & security