Installation¶
This guide covers prerequisites, installation, and Docker setup for local development and integration testing.
Prerequisites¶
- Python 3.12+ (3.13 and 3.14 are also supported — the CI matrix runs all three majors)
- Postgres: 15 is the minimum supported major; 15–18 are covered by CI —
the system-e2e tier runs its full multi-process lifecycle against every major
via a testcontainers version matrix.
docker-compose.ymlpins thepostgres:18image for local development (PG 18 is also what the fast test suite uses). No PG18-specific SQL exists in the bundled migrations; the floor is 15 because that is the oldest major the CI matrix exercises — older majors may work but are untested and unsupported. Production requires a direct connection (not PgBouncer in transaction-pooling mode) for advisory locks andLISTEN/NOTIFY. - Redis (optional): required only for real-time progress fanout and admin UI live updates.
- uv or pip for package management.
Install¶
Name check: the package is
taskq-py. There is an unrelatedtaskqdistribution on PyPI —pip install "taskq[redis]"installs that package, not TaskQ. Always use thetaskq-pyname.
pip install taskq-py # core only
pip install "taskq-py[redis]" # + real-time SSE fanout
pip install "taskq-py[fastapi]" # + admin UI
pip install "taskq-py[redis,fastapi]" # full
Or with uv:
Extras:
| Extra | Installs | Features enabled |
|---|---|---|
taskq-py[redis] |
redis>=8.0.1 |
Real-time progress fanout via Redis pub/sub, Redis-backed rate limiters (TokenBucket, SlidingWindow) |
taskq-py[otel] |
opentelemetry-sdk, opentelemetry-exporter-otlp, opentelemetry-instrumentation |
Configuring OTel providers programmatically; in-process test utilities in taskq.testing.otel |
taskq-py[fastapi] |
fastapi, jinja2, sse-starlette, uvicorn, humanize, python-multipart |
Admin UI (taskq ui serve), SSE progress bridge |
taskq-py[prometheus] |
opentelemetry-exporter-prometheus, prometheus-client |
Prometheus metric scrapes via taskq.contrib.prometheus |
taskq-py[oidc] |
authlib>=1.8, httpx2, itsdangerous |
OIDC/SSO auth backend for the admin UI; see SSO / SAML. The OIDC path uses httpx2 as its HTTP client (authlib ≥ 1.8 is httpx2-first); httpx is not installed by this extra |
taskq-py[saml] |
python3-saml, itsdangerous |
SAML/SSO auth backend for the admin UI; see SSO / SAML |
taskq-py[aad] |
azure-identity, aiohttp |
Azure Entra ID managed-identity DB auth; see Managed Identities |
taskq-py[aws] |
boto3 |
AWS IAM RDS auth for Postgres; see Managed Identities |
taskq-py[vault] |
hvac |
HashiCorp Vault dynamic credentials; see Managed Identities |
taskq-py[reload] |
watchfiles |
Autoreload of workers and the admin UI during local development |
taskq-py[bench] |
py-spy, pyinstrument |
Profilers for the benchmarks/ toolkit (spot-check profiling; nothing under src/taskq imports them) |
Without an extra installed, the corresponding feature degrades gracefully or raises a clear ImportError with install instructions:
| Feature | Without extra | Behavior |
|---|---|---|
| Progress fanout | No [redis] |
ctx.progress() still coalesces and flushes to Postgres. JobHandle.progress_stream() falls back to 500 ms PG polling. HTTP SSE endpoint returns 503. |
| Redis rate limiters | No [redis] |
TokenBucket(backend="redis") / SlidingWindow(backend="redis") raise ImportError at acquire time. Use backend="postgres" or backend="memory" instead. |
| Admin UI | No [fastapi] |
taskq ui serve raises ImportError. The admin UI requires FastAPI. |
| OTel SDK providers | No [otel] |
taskq.testing.otel raises ImportError. The library emits OTel API spans/metrics regardless (they are no-ops without a configured provider). |
| Prometheus bridge | No [prometheus] |
taskq.contrib.prometheus raises ImportError. |
Docker Compose for integration tests¶
The bundled docker-compose.yml starts Postgres, Redis, and the admin UI in one command.
This is the fastest path to a running local environment.
Services started:
| Service | Port | Notes |
|---|---|---|
postgres |
5432 | Postgres with max_connections=200, shared_buffers=256MB |
redis |
6379 | Redis without persistence (appendonly no) |
admin |
8080 | TaskQ admin UI (runs taskq ui serve --migrate on startup) on startup |
The admin service runs taskq ui serve --migrate which applies pending migrations before starting the UI. When
using the full compose stack you do not need to run migrations manually.
To start Postgres and Redis only (for running the worker locally outside Docker):
Environment setup¶
Copy the example env file and adjust as needed:
No env var is strictly required: TASKQ_PG_DSN defaults to
postgresql://taskq:taskq@localhost:5432/taskq. For any real deployment, set it to your
actual database.
# Direct PG DSN: sessions, LISTEN/NOTIFY, and advisory locks require this.
TASKQ_PG_DSN=postgresql://taskq:taskq@localhost:5432/taskq
# Schema name for all TaskQ tables. Override if multi-tenanting.
TASKQ_SCHEMA_NAME=taskq
# Optional. Enables real-time progress fanout and admin UI live updates.
TASKQ_REDIS_URL=redis://localhost:6379/0
TASKQ_SCHEMA_NAME is the one schema truth for every entry point: the worker, the CLI, and
the TaskQ client all resolve it (the client consults it whenever TaskQ(schema=...) is
omitted; an explicit schema= always wins). Keep it identical across every process that
enqueues or consumes: an enqueuer on a different schema than its workers lands jobs that are
never picked up, with no error raised.
PgBouncer
Advisory locks and LISTEN/NOTIFY require a direct Postgres connection. Do not point
TASKQ_PG_DSN at a PgBouncer endpoint in transaction-pooling mode. Use
TASKQ_PG_DSN_DIRECT and TASKQ_PG_DSN_POOLED to split traffic; see
Configuration.
TaskQ loads configuration through dotenvmodel with cascading .env discovery:
.env → .env.local → .env.{env} → .env.{env}.local, where {env} comes from the
ENV variable (default dev). Real environment variables take precedence over .env
files; see Configuration for the full resolution rules.
Run migrations¶
Apply all pending migrations before starting a worker:
The command is idempotent: re-running against an up-to-date schema is a no-op. To inspect applied and pending migrations without making changes:
Alternatively, set TASKQ_MIGRATE_ON_START=true to have the admin UI apply migrations
automatically at startup. Production workers should still run taskq migrate up manually
before the worker process starts.
Next steps¶
- Quick Start: Define an actor, start a worker, enqueue a job
- Actors:
@actordecorator reference - Workers: Worker configuration and lifecycle
- Configuration: All
TASKQ_*environment variables