finds.dev

// 8 picks · reviewed October 2026

The Best Open Source Background Job Queues in 2026

A job queue takes work out of the request cycle: send the email, resize the image, call the slow API, and let a worker do it on its own schedule, with retries if it fails. That's the whole job, but the eight tools here disagree hard on how to do it — what sits in the middle (Redis, Postgres, nothing), whether retries and scheduling are built in or paywalled, and whether the worker is a separate process or just running inside your web app.

The first cut is language — nobody is choosing between Celery and Sidekiq, since they only run on Python and Ruby respectively. Past that, the real decision is infrastructure: River and Hatchet skip Redis entirely and lean on Postgres you probably already run; Sidekiq and BullMQ assume Redis is already there and build fast, atomic queues on top of it; Hangfire does neither and just runs inside your existing .NET process. Pick based on what you're already operating, not what has the most stars.

  1. 01celery
  2. 02sidekiq
  3. 03Hangfire
  4. 04bullmq
  5. 05asynq
  6. 06river
  7. 07rq
  8. 08hatchet

★ 28,574PythonNOASSERTIONupdated Jun 2026

best for the default choice — broadest ecosystem, most integrations, most battle-tested

Celery is the one your colleagues already know. Ten-plus years as the default Python answer to background jobs means broker and backend support most of the others can't match — RabbitMQ, Redis, SQS, and Pub/Sub for transport, half a dozen options for results — plus canvas primitives (chains, groups, chords) for when one task needs to kick off three more.

That history comes at a cost. celery/app/defaults.py runs to hundreds of settings, and the docs don't always explain which ones interact, so a misconfigured deployment usually means guesswork. The default prefork pool forks OS processes, which plays badly with Django's database connections — a well-known source of stale-connection bugs that catches teams every year. And unlike everything else here, Celery's README says outright that Windows isn't a supported target.

If you just want enqueue-a-function-call without the weight, RQ is the smaller Python option below — Celery earns its complexity on real fanout or multiple brokers, but it's not where you start a small project.

★ 13,535RubyNOASSERTIONupdated Jun 2026

best for Ruby/Rails teams — the de facto standard there

Sidekiq is to Ruby what Celery is to Python — if you're on Rails, this is barely a decision. Threads instead of forked processes give it real throughput (23k jobs/sec on MRI, more under YJIT), and the middleware chain is a clean place to hang instrumentation without monkey-patching core classes.

The catch is Redis: it's not just a dependency, it's the only state your jobs have, so Redis going down means your queue is gone, not just stalled — there's no SQL-backed fallback the way Hangfire or River offer in their own ecosystems. And the features you'll actually want in production — cron, batches, rate limiting — live behind Sidekiq Pro or Enterprise, a paywall you'll hit faster than the marketing suggests, much like how BullMQ holds job groups and batching behind BullMQ-Pro.

Going through ActiveJob for Rails convenience costs roughly 2x throughput versus writing Sidekiq::Job directly — worth knowing before you assume the integration is free.

★ 10,078C#NOASSERTIONupdated May 2026

best for .NET teams who want jobs running inside the web app, no separate worker process

Hangfire's pitch is specific: no separate worker process, no extra service to deploy — jobs run inside the ASP.NET app you already have, with a dashboard thrown in for free. That's a real advantage over Celery or Sidekiq, which assume you're standing up dedicated workers from day one.

It's also where the simplicity ends. SQL Server storage polls the jobs table rather than getting pushed to, which is fine until you're at a scale where River's or BullMQ's event-driven backends don't carry that tax. The dashboard ships with no real authentication — just a filter that blocks non-local requests — and it's easy to expose job internals through a misconfigured proxy. Before adopting it somewhere with a legal review process, know the LGPL license comes with separate commercial and royalty-free license files, a murkier story than the MIT terms on most of the rest of this list.

Recurring jobs are CRON-only too, so anything needing 'run N minutes after the last run finished' semantics means writing DisableConcurrentExecution guards yourself.

★ 9,000TypeScriptMITupdated Jun 2026

best for Node.js/TypeScript teams already running Redis

BullMQ is the Node default for the same reason Sidekiq is Ruby's — it's Redis-backed, it's fast, and everything that matters (state transitions, rate limiting, stalled-job detection) runs as atomic Lua scripts so two workers can't race on the same job. The FlowProducer API for parent/child dependencies is genuinely useful for DAG-style pipelines, something only River and Hatchet handle as directly elsewhere on this list.

The multi-language story — Python, Elixir, Rust and PHP workers sharing the same Redis schema — sounds great until you check the PHP port's test suite, which is thin and covers only basic queue operations; don't build production infrastructure on the non-Node ports yet. Like Sidekiq, the genuinely interesting features — job groups, batch processing, group rate limiting — sit behind BullMQ-Pro, priced on request.

And if you outgrow a single Redis node, Cluster mode has real limitations around multi-key Lua scripts — you'll be hand-routing keys, not flipping a config flag.

★ 13,366GoMITupdated Jun 2026

best for Go teams who want a lean Redis-backed queue without a bigger platform bolted on

Asynq is what you reach for in Go when Celery feels like the wrong language and Hatchet feels like more platform than you need. The ServeMux-style API will feel immediately familiar to anyone who's written a Go HTTP handler, and weighted priority queues and task aggregation are both first-class instead of bolted on.

The honest problem is that it's still pre-1.0, with the maintainers saying directly that APIs can break before it stabilizes — a real risk if you're wiring this into something you don't want to revisit in six months. There's no typed task registry either, so a typo in a task-type string just silently routes nowhere instead of failing loudly, and you're on your own for idempotency since delivery is at-least-once, not exactly-once.

Compare that to River, the other lean Go option here: River trades Redis for Postgres and gets transactional guarantees Asynq simply can't offer, at the cost of needing Postgres instead of whatever you already have running.

★ 5,361GoMPL-2.0updated Jun 2026

best for teams on Postgres who don't want to run Redis at all

River's whole argument is one sentence: enqueue jobs inside the same Postgres transaction as the work that created them, so a rolled-back transaction means the job never existed. That closes a category of phantom-job bugs that Asynq, BullMQ, and every other Redis-backed queue here can't close, because enqueue and commit are two separate systems for them.

The cost shows up in the packaging: riverdriver, rivershared, rivermigrate, and the SQLite driver are all separate Go modules, so version-pinning across a larger codebase is more fiddly than it should be. SQLite support exists but is clearly second-class — it fakes LISTEN/NOTIFY with a notification outbox, a workaround with different reliability characteristics that isn't well documented. The web UI also lives in its own repo with its own release cadence, so UI and library versions can quietly drift out of sync.

If your job producers need to be polyglot, Python and Ruby can only insert jobs into River — writing an actual worker still means Go, unlike Hatchet, which has full SDK parity across Go, Python, and TypeScript.

★ 10,650PythonNOASSERTIONupdated Jun 2026

best for small Python projects where Celery's configuration overhead isn't worth it

RQ exists because Celery's configuration surface is a lot to take on for a project that just needs background jobs. Enqueue a function, start a worker, done — no separate DSL, no hundreds of settings to understand before your first job runs. The 2.5 release added a built-in cron scheduler, closing the gap that used to require a separate rq-scheduler sidecar.

The real problem is the default serializer: RQ uses pickle, and deserializing attacker-controlled data with pickle is remote code execution, not a theoretical concern. That warning sits in a box partway down the README instead of JSONSerializer just being the default — switching should be step one, not an afterthought. There's also no result backend beyond a Redis key TTL, so durable job history is on you, and the worker pool doesn't auto-scale — you're back to managing process counts through systemd or Kubernetes at any real load.

It's the right choice specifically when Celery is overkill for your Python project, not a general substitute for it — the two aren't really competing for the same job.

★ 7,038GoMITupdated Apr 2026

best for teams who want durable retries and a monitoring dashboard built in, not bolted on separately

Hatchet sits a level above everything else on this list — it's not just a queue, it's DAG orchestration, durable execution with sleep/event-wait, per-key concurrency limits, and a dashboard, all running on Postgres the way River does. If you've outgrown what BullMQ or Asynq give you but don't want Temporal's operational weight, this is the gap it's built to fill, and the README is unusually honest about that positioning instead of pretending to replace everything.

Getting there means accepting real self-hosting complexity: Postgres, a message bus, and several internal services, mostly hidden behind a Docker quickstart that doesn't prepare you for production deployment, which is sparsely documented. The quoted ~10k/s throughput ceiling is stated without nuance — no published benchmarks, no breakdown by hardware or task size — so treat it as a rough signal, not a planning number. The Go SDK is also the clunkiest of the three languages offered; the Python and TypeScript SDKs read considerably more naturally.

It ships a full multi-tenant RBAC model whether you need it or not — a solo project or small team self-hosting Hatchet has no easy way to opt into a simpler single-tenant setup.

// questions people ask

Before you choose

Should I pick based on language or based on infrastructure?

Language first — nobody picks between Celery and Sidekiq, since they only run on Python and Ruby respectively. Once you're inside one language's options, like Asynq versus River versus Hatchet in Go, infrastructure is what actually separates them: what's already running, and what you're willing to add.

Do I need Redis for a background job queue?

No. Sidekiq, BullMQ, and Asynq are all built on Redis and it's not optional for them, but Hangfire uses SQL Server, and River and Hatchet both run on Postgres instead. If you don't already run Redis, River or Hatchet avoid adding it, provided you're on Postgres already.

Which of these have features locked behind a paid tier?

Sidekiq and BullMQ both hold back their more advanced features — cron, batching, and rate limiting for Sidekiq; job groups and batch processing for BullMQ — behind Sidekiq Pro/Enterprise and BullMQ-Pro. Celery, RQ, Hangfire, Asynq, River, and Hatchet ship their core feature sets free; Hangfire's paid tier mostly exists to replace SQL Server polling with push-based scaling.

Is there a safe default if I just want something simple in Python or Go?

In Python, start with RQ unless you already know you need Celery's canvas primitives or multi-broker support — Celery's configuration surface is a lot to take on for a small project. In Go, Asynq is the leanest option; reach for River once you're on Postgres and want transactional job creation, and Hatchet only once you need orchestration, not just a queue.

None of these are wrong, exactly — they're built for different stacks and different tolerances for added infrastructure. If you want repos like this showing up before you go looking for them, that's what the weekly finds.dev email does.

// how we picked these

Every repo here was read and assessed on its own before it was considered for this page: we pull the README, the directory layout and a key source file, and write the assessment from those rather than from the project's own marketing. Candidates for this list came from a full-text and topic search over the 230 reviewed repositories that matched this category. Anything with no commit in the last 12 months was cut, as were link collections, tutorials and boilerplates; the floor for inclusion was 1.000 stars. The ordering is a judgement call about who should pick what, not a ranking by stars. finds.dev is independent of every project listed here: nobody paid for a place on this page, there are no affiliate or referral links on it, and we have no commercial relationship with any of them. That is the point of writing down what each one is bad at as well as what it is good at.

Our criteria →