JOB 03Introduction

Comparison

This table compares VarMQ with ants, pond v2, conc, workerpool, errgroup and gopool. The cells are the same as in the feature comparison in the README. The notes marked VarMQ limit are new here: they say where a VarMQ Yes has a limit.

How to read it. Every row is a feature VarMQ has, so the VarMQ column reads Yes all the way down. The table does not list features that another library has and VarMQ lacks. Where a VarMQ Yes has a limit, the row has a VarMQ limit note, with the page of these docs that explains it. For speed, see the benchmarks.
Features of VarMQ, ants, pond, conc, workerpool, errgroup and gopool. Each cell says Yes or No.
Featurevarmqantspondconcworkerpoolerrgroupgopool
Generic (type-safe) APIYesYesYesYesNoNoNo
Tasks return results and errorsVarMQ limit On shared storage too: the job handle learns the outcome from the process that ran the job. Worker typesYesNoYesYesNoNo2No
Task groups (submit many, wait once)VarMQ limit AddAll works on in-memory queues and on shared storage. Persistence overviewYesNoYesYesNoYesNo
Priority queueYesNoNoNoNoNoNo
Persistent queues (survive restarts)VarMQ limit VarMQ has no adapter of its own: you add redisq (Redis) or sqliteq (SQLite). The best case is at-least-once delivery, so a job can run twice. What this guaranteesYesNoNoNoNoNoNo
Distributed queues (across instances)VarMQ limit Of the existing adapters, only redisq (Redis) provides one. sqliteq has no distributed queue. An adapter of your own can implement IDistributedQueue. SQLiteYesNoNoNoNoNoNo
Several queues bound to one poolYesNoYes4NoNoNoNo
Topic fan-out (publish once, many pools)VarMQ limit Topics are in-memory only. To share jobs between processes, use a distributed queue. TopicsYesNoNoNoNoNoNo
Bounded queue, reject when fullVarMQ limit Not with redisq or sqliteq. Neither implements CapacitySetter, so Add is not refused on their persistent or distributed queues. An adapter of your own can implement it. Persistence overviewYesYesYesNoNoNo3No
Pause and resumeVarMQ limit On a persistent or distributed queue, Pause and Stop do not park a job the worker already took. It runs. AcknowledgementYesNoNoNoYesNoNo
Restart after stopYesYesNoNoNoNoNo
Resize pool at runtimeYesYesYesNoNoNoYes
Cancel work via contextVarMQ limit Cancelling the context shuts the worker down. A running job is not interrupted: VarMQ cannot stop a function. Jobs that wait do not start. ContextYesNoYesYesNoYesNo
Panic recoveryYesYesYesNo1NoNoYes
Task counters (submitted, failed, ...)YesNoYesNoNoNoNo
Built-in REST APIYesNoNoNoNoNoNo
  1. conc re-raises a task’s panic from Wait by design.
  2. errgroup returns the first error, no results.
  3. errgroup has no queue; TryGo only refuses a task while every slot is busy.
  4. pond subpools: each has its own queue and runs on the parent pool’s workers.

Checked against each package’s source, October 2026.

What this page leaves out

This table covers in-process worker pools only. The benchmarks also measure Redis job queues (Asynq, gocraft/work, rmq, taskq) and SQLite job queues (goqite, Backlite, River). This page has no feature table for them.

For how fast each one runs, see the benchmarks, with the raw data in goptics/benchmarks, and the bench log.

Next: Installation.

Edit page

Last updated: