A robust and production-proven CLI-based work queue system with worker management, automatic retrying of failed jobs and support for dead letter queues.
QueueCTL is the command line interface for managing your background jobs with queue and worker. It offers a simple but powerful API for enqueuing, processing and monitoring background jobs, with native support for retry and dead letter queue. You can run it purely from the CLI or pair it with a web dashboard for live job tracking and DLQ management.
- Job Management: Enqueue, list and monitor background jobs.
- Worker Pool: Start multiple worker processes concurrently.
- Automatic Retries: Exponential backoff for failed jobs can be automatically retried.
- Dead Letter Queue: Processed jobs that failed forever will go to seperate table that is DLQ .
- Persistence: Job state survives restarts.
- CLI Interface: User-friendly CLI with informative output.
- Node.js (v14 or higher)
- npm (v6 or higher) or yarn
-
Clone the repository
git clone https://github.com/Rupeshkotha/Queuectl cd queue_ctl -
Install dependencies
npm install
-
Link the CLI tool globally This allows you to run
queuectlfrom anywhere in your terminal.npm link
-
Verify installation
queuectl --version
You will see the current version of QueueCTL.
To start the web dashboard, use the following command:
nodemon dashboard.jsThis will start the dashboard server. By default, it runs on http://localhost:8080.
-
Real-time Status Overview
- Shows Current job queue status at a glance
- Shows Number of Processing, Pending, Failed, Dead and Completed jobs
- Shows Active Workers
-
Interactive Job Tables
- Seperate tables listed for every state (Processing, Pending, Failed, Dead and Completed jobs)
- Color-coded job status indicators
- Click any status to view detailed job information in a modal
-
Dead Letter Queue (DLQ) Management
- View all failed jobs that exceeded retry limits
- Error messages and stack traces
QueueCTL employs SQLite as the underlying persistence store. The database file (jobs.db) will be created automatically in the root of your project when you execute the application for the first time.
-
Permission Denied If you get permission errors while running
npm linktry:sudo npm link
-
Command Not Found If you still can't find the
queuectlcommand after linking, make sure that npm's global bin directory is on your PATH:export PATH=$PATH:$(npm get prefix)/bin
Add this line to your shell's configuration file (
.bashrc,.zshrc, etc.) to make it permanent. -
Database Issues If you get database errors, delete the
jobs.dbfile and restart the application to generate a new database.
For detailed test cases and verification steps, please refer to the TESTING.md file. This document includes:
- Test scenarios for all major features
- Step-by-step verification procedures
- Expected outcomes for each test case
- Scheduled jobs execution using
available_attimestamps (instead ofrun_atI have named asavailable_atand this timestamp indicates that worker can process it only at this time stamp) - web dashboard Interface
- Job output logging (Run
node worker.jsfor output logs)
QueueCTL is simple and robust at its core, based on modular structure that cleanly separates CLI, job processing, and data storage. It's lightweight, but powerful you can use it to perform background job processing with very little fuss.
QueueCTL relies on solid SQLite database that maintains data integrity even if you have to restart the app. The schema is defined with 3 main tables:
-
Jobs Table: The primary source of active jobs, containing all job data such as the command to execute, its current state, how many retry attempts it has had and timestamps etc. The
available_atfield supports deferred job execution, and theexit_codeholds the executed command's exit code. -
Dead Letter Queue (DLQ): A special table to store the failed jobs after all retry attempts. It’s the safety blanket of the process, and it means that the admins never lose sight of the problematic jobs and may take a closer look on them, or even requeue them.
-
Configuration Table: A very basic key value pair for global configurations which makes the application highly configurable without the need of changing any code. This covers parameters such as the maximum number of retry attempts and backoff policies.
Jobs QueueCTL jobs adhere to a precisely defined lifecycle that guarantees treatment reliability. When a new job is enqueued, it enters the system with a “pending” status. Workers poll for pending jobs in a tight loop and turn them into “processing” jobs as they work. Success completion transitions jobs into completed state and failure triggers retry mechanism with exponential backoff. Jobs that have used all their retries are sent to the dead letter queue for manual processing.
The worker is intended to be both lean and resilient. N worker processes may run in parallel, all independently polling for work on the jobs queue. The system uses database locking to avoid duplicate work on jobs, so each job is really processed by a single worker. Workers successfully trap process exiting signal and perform leading three step checkout process to do a clean exit before killing themselves.
QueueCTL has a comprehensive error mechanism that distinguishes between transient and permanent errors. Transient errors result in the exponential backoff retrying (at each retry attempt, the time between retries increases exponentially). The system also stores much more detailed information about errors, such as error messages, exit codes and more for debugging and monitoring purposes.
The behavior of the system can be modified through runtime configuration and stored in the database settings. This layered approach lets you specify default configurations for the entire system, as well as override them for specific deployments. Changes to configuration take immediate effect, without the need to restart the system, allowing the system to be customized to different operating environments. by default max retires will be 3 and exponential backoff value will be 2
The exponential backoff policy is used when fetching failed jobs. Doing so prevents systems from being flooded by transient failures, and also reduces contention.
The backoff time is calculated as backoff_base ^ attempts in seconds where backoff_base is a configurable parameter (default value 2) and attempts is the number of attempts to retry the job.
first failure wait 2 seconds (2¹) before retrying. After that, if it fails again, the wait time is doubled to 4 seconds (2²), and after the third failure, it backs off 8 seconds (2³). When job fails more than maximum times (default 3), it is re-queued to dead letter queue for manual examination. Consequently, this exponential backoff in wait times eases the system’s load and allows for better recovery from transitory faults.
- Running on Node.js with a single SQLite database file
- Moderate job volume (not designed for thousands of jobs per second)
- Jobs complete within a reasonable time (not long-running processes)
- No need for distributed processing across multiple machines
- Both CLI and web dashboard access available
- Commander.js for building the CLI interface
- Simple and well-documented
- Good community support
- Built-in help generation
- Express.js for the web dashboard
- Lightweight and fast
- Easy to integrate with existing Node.js code
- Large ecosystem of middleware
- SQLite for data persistence
- Zero-configuration database
- Single file storage
- Chalk & Ora for CLI UX
- Better terminal output formatting
- Loading spinners for better user feedback
- Chose SQLite for simplicity over distributed databases
- Single-node architecture limits horizontal scaling
- Basic error handling without complex recovery
- Web dashboard provides visual monitoring alongside CLI
- Commander.js - Complete solution for Node.js command-line interfaces
- SQLite3 - Asynchronous SQLite3 database driver
- Chalk - Terminal string styling
- Figlet - ASCII art text generator
- Ora - Elegant terminal spinner
- Boxen - Create boxes in the terminal
- cli-table3 - Beautiful formatted tables
