# Huey: a little task queue, five storages, one consumer command

> Huey is Charles Leifer's lightweight task queue for Python: background execution, crontab-style schedules, retries, pipelines and chords, with state in Redis, Postgres, SQLite, the file system or memory. The core installs zero dependencies and the consumer is a single command.

**coleifer/huey** — a little task queue for python

- Repository: https://github.com/coleifer/huey
- Website: https://huey.readthedocs.io/
- Stars: 6,041 · Forks: 402
- Language: Python
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/coleifer-huey

## A lightweight alternative, named after a cat

Huey introduces itself as a lightweight alternative, and the framing holds up in the package's own metadata: the core installs zero dependencies, and the optional extras are single-purpose, redis-py for Redis-like brokers, psycopg>=3.2 for Postgres, peewee>=3.17 for the stats extension. The author is Charles Leifer, and the appearance of peewee in the extras is the fingerprint of the same hand behind that ORM. Storage choices span Redis, including the valkey and redict alternatives, Postgres, SQLite, the file system and plain in-memory, so a project that already runs Postgres does not have to introduce Redis to get a queue. The name, per the README, honors the author's cat, which sets the register of the whole project: small, personal in origin, and practical rather than architectural. Classifiers call the package Production/Stable for developers, the code lives in a single huey tree, and the one console script it installs is huey_consumer, mapped to huey.bin.huey_consumer:consumer_main.

## Three decorators cover most of the API

The advertised API is close to the whole API. A queue instance, then decorators:

```python
from huey import RedisHuey, crontab

# Or PostgresHuey, SqliteHuey, FileHuey, etc...
huey = RedisHuey('my-app', host='redis.myapp.com')

@huey.task()
def add_numbers(a, b):
    return a + b
```

Retries are declared at decoration time, with counts and delays as arguments rather than wrapper code:

```python
@huey.task(retries=2, retry_delay=60)
def flaky_task(url):
    # This task might fail, in which case it will be retried up to 2 times
    # with a delay of 60s between retries.
    return this_might_fail(url)

@huey.periodic_task(crontab(minute='0', hour='3'))
def nightly_backup():
    sync_all_data()
```

A crontab object drives recurring work, so a nightly three o'clock backup is one decorator argument instead of a scheduler daemon. Everything beyond these three shapes, priorities, expiration, locking, lives in the same declarative style.

## Call the function, get a handle back

Invoking a decorated function does not run it, it enqueues it, and what returns immediately is a result handle rather than a value:

```python
>>> from demo import add_numbers
>>> res = add_numbers(1, 2)
>>> res
<Result: task 6b6f36fc-da0d-4069-b46c-c0d4ccff1df6>

>>> res()
3
```

Calling the handle fetches the finished result from task result storage. Scheduling future work keeps the same shape, with an optional blocking wait:

```python
>>> res = add_numbers.schedule((2, 3), delay=10)  # Will be run in ~10s.
>>> res(blocking=True)  # Will block until task finishes, in ~10s.
5
```

That symmetry, execute-now and execute-later both returning the same handle type, is a large part of why the API reads as small: there is one mental model for deferred work, and the blocking flag is there when a caller genuinely must wait.

## One consumer command, three execution models

Execution happens in a separate consumer process, and the command line is where its shape is chosen. The default is a single worker thread:

```bash
huey_consumer my_app.huey
```

Four worker processes for CPU-shaped work:

```bash
huey_consumer my_app.huey -k process -w 4
```

And greenlets for IO-bound loads, where the documentation notes you can run quite a few of them efficiently because they are so lightweight:

```bash
huey_consumer my_app.huey -k greenlet -w 32
```

The -k flag selects the execution model, process, thread or greenlet, and -w the worker count. Because the consumer lands on PATH as a console script, these variations are system-unit edits rather than code changes, one service definition per model. Multi-process, multi-thread and greenlet execution are all first-class, which is unusual at this size: most small queues pick one concurrency answer and stick to it, while Huey makes it a deployment decision you can revisit without touching task code.

## Redis-informed, but not Redis-required

The storage story is honest about its history. Huey's design and feature set were informed by the capabilities of Redis, which the README calls a fantastic fit for a lightweight queue: self-contained, versatile, and useful for the rest of a web application's needs, caching, event publishing, analytics, rate-limiting. But the storage layer implements a simple API, so alternatives plug in, and the built-in set covers Redis, Postgres, SQLite, the file system and in-memory operation. The extras map to the choices that need a driver, redis>=3.0.0, psycopg>=3.2, and a cysqlite extra at >=0.3.5 for a faster SQLite path, with a legacy backends alias that still points at redis for older deployments. For a small service, running the queue on the Postgres you already have, or on the file system for a single-box cron replacement, is the difference between adopting a queue and not, and the in-memory option rounds out the list for processes that need no persistence at all.

## Django admin, flask-peewee, and stats for everyone else

Framework integration leans on visibility. Django support works natively or through django.tasks, and an optional admin integration shows queued and running work inside Django's admin for management, not just monitoring. A flask-peewee admin integration exists based on the same underlying stat-tracking system, and for any other framework the stats extension collects and exposes the same information, with peewee>=3.17 as its dependency. The package data in pyproject.toml confirms the shape, shipping HTML templates for both the Flask admin panel and the Django djhuey stats views. The point of this layer is that a background system you cannot see is a background system you cannot trust, and Huey treats observability as bundled rather than third-party.

## Pipelines, chords and the rest of the list

Past the basics, the supported list reads like a much larger system's: task prioritization, result storage, task expiration, task locking, rate-limits, timeouts, pipelines and chains, plus groups for fan-out and chords for map/reduce shapes. Pipelines chain steps so each receives the previous result, groups launch a batch of independent tasks at once, and chords run a callback across the results of many tasks, the reduce half of map/reduce. None of that requires extra infrastructure beyond the storage choice, which is the consistent bet of the design. Example code is organized by scenario, examples/simple, examples/mini, examples/django_ex and examples/flask_ex, plus an examples/deploy directory, and the changelog tracks releases that arrive steadily, 3.3.3 and 3.3.4 in August 2026, 3.4.0 on 2026-09-04, with the last push on 2026-09-15. The comparison set is real: Celery and Dramatiq cover the same problem with more machinery, and Huey's answer is that most services need the feature list, not the framework around it.

## Conclusion

Choose Huey when a background worker should be a small, readable part of an ordinary Python service, and the broker list, Redis or Postgres or SQLite or the file system, matches what you already run. Choose Celery or Dramatiq when you need their broader machinery and accept the heavier configuration surface that comes with it. Verify first which storage backend you will standardize on and install its extra, since the core package ships without redis-py or psycopg, and decide the execution model, process, thread or greenlet, before sizing worker counts.

## FAQ

### What is Huey in Python?

Huey is a lightweight task queue for Python by Charles Leifer, with a clean API for running functions in the background, on crontab-style schedules, or with automatic retries. State can live in Redis, Postgres, SQLite, the file system or memory.

### How do you run the Huey consumer?

Run huey_consumer my_app.huey for a single worker thread, add -k process -w 4 for four worker processes, or -k greenlet -w 32 for many lightweight greenlets. The -k flag selects the execution model and -w sets the worker count.

### Does Huey require Redis?

No. Redis, including the valkey and redict alternatives, informed the design, but built-in storage also covers Postgres, SQLite, the file system and in-memory. The core installs zero dependencies; redis-py or psycopg arrive only with the corresponding extra.

## Sources

- [coleifer/huey on GitHub](https://github.com/coleifer/huey)
- [License: MIT](https://github.com/coleifer/huey/blob/master/LICENSE)
- [Project website](https://huey.readthedocs.io/)
- [README](https://github.com/coleifer/huey/blob/master/README.md)
- [Releases](https://github.com/coleifer/huey/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/coleifer-huey
