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 amber notes 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 says so in amber, with the page of these docs that explains it. For speed, see the benchmarks.
| Feature | varmq | ants | pond | conc | workerpool | errgroup | gopool |
|---|---|---|---|---|---|---|---|
| Generic (type-safe) API | Yes | Yes | Yes | Yes | No | No | No |
| Tasks return results and errorsvarmq limit Only on in-memory queues. On a persistent or distributed queue, Add returns a bool and no job handle, so there is nothing to Wait on and no Err or Result to read. Worker types | Yes | No | Yes | Yes | No | No2 | No |
| Task groups (submit many, wait once)varmq limit Only on in-memory queues. A persistent or distributed queue has no AddAll. Persistence overview | Yes | No | Yes | Yes | No | Yes | No |
| Priority queue | Yes | No | No | No | No | No | No |
| 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 guarantees | Yes | No | No | No | No | No | No |
| 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. SQLite | Yes | No | No | No | No | No | No |
| Several queues bound to one pool | Yes | No | Yes4 | No | No | No | No |
| Topic fan-out (publish once, many pools)varmq limit Topics are in-memory only. A persistent topic was built and removed before release, so it is not part of v1.10.0. Persistent topics | Yes | No | No | No | No | No | No |
| 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 overview | Yes | Yes | Yes | No | No | No3 | No |
| Pause and resumevarmq limit On a persistent or distributed queue, Pause and Stop do not park a job the worker already took. It runs. Acknowledgement | Yes | No | No | No | Yes | No | No |
| Restart after stop | Yes | Yes | No | No | No | No | No |
| Resize pool at runtime | Yes | Yes | Yes | No | No | No | Yes |
| 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. Context | Yes | No | Yes | Yes | No | Yes | No |
| Panic recovery | Yes | Yes | Yes | No1 | No | No | Yes |
| Task counters (submitted, failed, ...) | Yes | No | Yes | No | No | No | No |
| Built-in REST API | Yes | No | No | No | No | No | No |
No row matches.
- conc re-raises a task’s panic from
Waitby design. - errgroup returns the first error, no results.
- errgroup has no queue;
TryGoonly refuses a task while every slot is busy. - pond subpools: each has its own queue and runs on the parent pool’s workers.
Checked against each package’s source, October 2026.
For how fast each one runs, see the benchmarks, with the raw data in goptics/benchmarks, and the bench log.
VarMQ is MIT licensed. Benchmark figures come from github.com/goptics/benchmarks.