I'm the maintainer of node-cron (5M+ downloads/month), and I recently built Sidequest.js, a background job runner for Node.js inspired by Oban (Elixir) and Sidekiq (Rails).
It solves some common problems I saw with libraries like node-cron:
- Jobs don’t block your API: they run in isolated worker threads
- No Redis or vendor lock-in: use Postgres, MySQL, SQLite, or MongoDB
- Supports retries, uniqueness, concurrency, snoozing, prioritization
- Comes with a CLI and a simple dashboard
- Works great in monoliths and doesn’t require extra infra
Quick start (no signup needed): https://docs.sidequestjs.com/quick-start
GitHub: https://github.com/sidequestjs/sidequest
Would love feedback or feature suggestions. Happy to answer any questions here!
If you’re running Sidequest entirely on your own infrastructure to orchestrate jobs across your backend, you’re not distributing the software at all, you’re providing a service. The tight coupling does not itself trigger extra obligations. What matters legally is distribution, not architecture.
Edgecase is if you give your software to a customer to run on their own servers (self‑hosted deployment/docker image shipped to customer). In those cases, you would need to allow them to replace Sidequest.js (ie, not obfuscating it away).
Someone more knowledgeable can correct me, if I'm wrong
https://www.gnu.org/licenses/gpl-faq.html#AGPLv3ServerAsUser
Which is a good way to get improvements other are doing that relate to your source code through LGPL's source exposing, while not forcing it everywhere (GPL case). Especially, for backend libs.
And since AGPL will essentially make it non viable for SaaS (as network separation won't do), LGPL is what left.
I also like that there's a dashboard. That's really important when a project gets serious, and a surprising number of job queue libraries don't have admin tools.
Just to validate an idea here: I’m using k8s (20+ services) and trying to stick to the 12factor design pattern by having all the baking/companion services, also like cron jobs deployed from within the service directory. Right now I’m using k8s cron services for cron jobs and log the steps and observe with DataDog. Using k8s cron services feels right somehow but the observability with DataDog not. So, would it make sense for me, to deploy a baking k8s web service running sidequest instead?
You can probably deploy Sidequest a job processor for all your 20+ services. Each service can enqueue the jobs and you can run as many machines as you want with Sidequest just to run the jobs. You maintain the 12-factor principle - your services remain stateless and delegate scheduled work to Sidequest.
The only requirement here is that the scripts to be executed must be in the same path in all machines. As long as you follow that, you can deploy it and run your jobs :)
Graphile Worker: PostgreSQL only
Sidequest: Multiple backends (PostgreSQL, MySQL, SQLite, MongoDB)
Graphile Worker: No built-in dashboard - you need external monitoring
Sidequest: Comprehensive built-in web dashboard for job monitoring
Graphile Worker: Single queue with job prioritization
Sidequest: Multiple queues with individual: i) Concurrency limits; ii) Priority levels; iii) State management (active/paused); iv) Isolated workloads.
Graphile Worker: Direct PostgreSQL integration, very lightweight
Sidequest: Worker threads for non-blocking processing, more comprehensive job lifecycle management
Graphile Worker: Optimized for PostgreSQL performance (3ms latency)
Sidequest: Balanced performance with rich feature set
I hope that helps answering your question.
Great question!
Sidequest uses transaction-level row locks (`SELECT ... FOR UPDATE SKIP LOCKED`) when fetching jobs. This means each worker thread only locks the specific job rows it’s about to process, minimizing lock contention and avoiding blocking other queries. This pattern is inspired by Oban’s advisory-lock approach, but instead of using explicit advisory locks, Sidequest relies on the database’s built-in row locking mechanism.
The only drawback is that Sidequest will require one or two connections to your DB. If you enqueue jobs from within other jobs, then each job that requests an enqueue will also connect to your DB (lazily connected upon request - if your job does not enqueue, no connection is created). However, you can configure the number of concurrent workers per queue and globally, so you control how much load Sidequest puts on your database.
I hope that answers your question :)
If you have heard of pg-boss [1], how does sidequest compare to it? I’m about to embark on some « jobification » on some flows and I’d love to have your opinion (possibly biased, but still)!
Database agnostic: Sidequest isn't tied to Postgres. It also works with MySQL, MongoDB, and SQLite, which helps if your stack isn’t Postgres-based.
Job isolation: Jobs run in worker threads, so heavy tasks won’t block your main Node.js process. Express APIs stay responsive.
Distributed coordination: Designed to run across multiple instances. One node picks up the job, and if it fails, another can retry. This is built-in.
Built-in dashboard: Includes a web UI to inspect, retry, or cancel jobs.
More than queues: Supports cron jobs, uniqueness constraints, per-queue concurrency, and configuration. Some of this overlaps with pg-boss, but the intent behind Sidequest is to provide a complete solution for job processing.
If you just need simple queues in a Postgres-only setup, pg-boss is great. If you want more flexibility, tooling, and backend options, Sidequest may be a better fit.
I'm all in with Postgres, but the job isolation + built-in dashboard seem really appealing. I'll definitely give it a try!
Keep up the great work, love to see such high quality codebase / documentation / tooling!
The main conceptual one is that BullMQ enqueues plain objects, and your handler just receives that data. In Sidequest, you enqueue full class instances, so when the job runs you can call this.someMethod() directly inside run().
Sidequest also runs jobs in isolated worker threads out of the box, has a built-in dashboard in the OSS version, and works with Postgres, MySQL, SQLite, or MongoDB.
That said, I still want to explore BullMQ more deeply to write a complete comparison.