Redis-based statedb persistence for Celery workers
Project description
Celery Redis StateDB
Redis-based state persistence for Celery workers in containerized environments.
This package provides a Redis-based backend for Celery's worker state persistence, replacing the default filesystem-based shelve storage. It's designed to:
- ✅ Persist revoked task state across container restarts
- ✅ Isolate state per worker using unique key prefixes
- ✅ Eliminate concurrency issues through per-worker key isolation
- ✅ Handle Redis connection failures gracefully
- ✅ Integrate seamlessly with existing Celery applications
Features
- Distributed State Persistence: Store revoked tasks in Redis instead of local files
- Per-Worker Isolation: Each worker maintains its own state using unique key prefixes based on hostname
- Concurrency-Safe: No race conditions since workers never write to the same keys
- Easy Integration: Simple Celery bootstep that works with existing applications
Installation
# Using pip
pip install celery-redis-statedb
# Using uv
uv add celery-redis-statedb
Quick Start
Method 1: Command Line (Easiest)
The easiest way to use Redis state persistence is via the --redis-statedb command line option:
celery -A myapp worker --redis-statedb=redis://localhost:6379/0
Method 2: Programmatic Installation (Recommended)
Use the install_redis_statedb() convenience function in your app:
Basic usage (with defaults):
from celery import Celery
from celery_redis_statedb import install_redis_statedb
app = Celery('myapp')
# Install Redis state persistence
install_redis_statedb(app)
# Start worker with Redis statedb
# celery -A myapp worker --redis-statedb=redis://localhost:6379/0
With custom configuration:
from celery import Celery
from celery_redis_statedb import install_redis_statedb
app = Celery('myapp')
# Optional: Configure via app.conf
app.conf.redis_state_key_prefix = 'myapp:worker:state:'
# Install bootstep
install_redis_statedb(app)
# Start worker
# celery -A myapp worker --redis-statedb=redis://localhost:6379/0
Method 3: Environment Variables
Configure additional settings via environment variables:
# Optional: Custom key prefix (default: celery:worker:state:)
export CELERY_REDIS_STATE_KEY_PREFIX=myapp:worker:state:
# Start worker
celery -A myapp worker --redis-statedb=redis://localhost:6379/0 --loglevel=info
Configuration Options
Configuration can be set via Celery app configuration (app.conf) or environment variables:
| Configuration Key | Environment Variable | Default | Description |
|---|---|---|---|
redis_state_key_prefix |
CELERY_REDIS_STATE_KEY_PREFIX |
celery:worker:state: |
Base prefix for Redis keys (worker hostname is appended) |
Example using app.conf:
app.conf.redis_state_key_prefix = 'myapp:worker:state:'
Example using environment variables:
export CELERY_REDIS_STATE_KEY_PREFIX=myapp:worker:state:
Revoked Task Persistence
Revoked tasks persist indefinitely in Redis (matching Celery's default behavior with shelve). This ensures that once a task is revoked, it remains revoked even across worker restarts.
Celery's LimitedSet automatically purges expired items based on the maxlen parameter (default: 10000 items). When the set reaches this limit, the oldest items are automatically removed to maintain the size constraint.
Architecture
Per-Worker Key Isolation
Each worker maintains its own state using a unique key prefix based on the worker's hostname:
celery:worker:state:<worker-hostname>:zrevoked
celery:worker:state:<worker-hostname>:clock
This design eliminates concurrency issues since:
- Workers never write to the same Redis keys
- No locks or atomic operations needed
- Simple, fast, and scalable
- Each worker independently manages its own state persistence
When a worker restarts, it loads its own state from its dedicated keys in Redis.
Worker Hostname Configuration
Default Hostname Behavior
By default, Celery generates worker hostnames in the format celery@<system-hostname>. In containerized environments:
- Docker: Uses the container ID (e.g.,
celery@f9207bc94b22) - Kubernetes: Uses the pod name (e.g.,
celery@worker-deployment-7d9f8b6c-xk2p5) - ECS: Uses the task ID or container hostname
Each container automatically gets a unique hostname, ensuring per-worker key isolation works correctly.
Customizing Worker Hostnames
For better visibility and debugging, you can set custom worker hostnames using the -n or --hostname option:
# Static name with system hostname
celery -A myapp worker -n worker1@%h --redis-statedb=redis://localhost:6379/0
# Using environment variable for replica number (Kubernetes)
celery -A myapp worker -n worker-$REPLICA_ID@%h --redis-statedb=redis://localhost:6379/0
# Custom name with domain
celery -A myapp worker -n myworker@example.com --redis-statedb=redis://localhost:6379/0
Hostname Variables:
%h- Full hostname with domain (e.g.,george.example.com)%n- Hostname only (e.g.,george)%d- Domain only (e.g.,example.com)
Note: In Supervisor config files, escape % as %% (e.g., %%h).
Multiple Workers on Same Host
When running multiple workers on the same machine, ensure each has a unique hostname:
celery -A myapp worker -n worker1@%h --redis-statedb=redis://localhost:6379/0
celery -A myapp worker -n worker2@%h --redis-statedb=redis://localhost:6379/0
celery -A myapp worker -n worker3@%h --redis-statedb=redis://localhost:6379/0
⚠️ Important: If multiple workers share the same hostname, they will overwrite each other's state in Redis. Celery will also show a DuplicateNodenameWarning. Always ensure unique worker hostnames in production.
Container Deployments
AWS ECS Deployment
Example ECS task definition with custom worker hostname:
{
"family": "celery-worker",
"containerDefinitions": [
{
"name": "celery-worker",
"image": "myapp:latest",
"command": [
"celery",
"-A",
"myapp",
"worker",
"-n", "worker@%h",
"--redis-statedb=redis://redis.cluster.local:6379/0",
"--loglevel=info"
]
}
]
}
Best Practices for ECS:
- Set
stopTimeoutto allow graceful shutdown (e.g., 120 seconds for 2-minute tasks)
Troubleshooting
Verify Worker Hostnames
To check that each worker has a unique hostname, inspect active workers:
# List all active workers
celery -A myapp inspect active
# Check worker stats (shows hostname for each worker)
celery -A myapp inspect stats
Check Redis Keys
To verify per-worker keys are being created correctly:
# Connect to Redis
redis-cli
# List all worker state keys
KEYS celery:worker:state:*:zrevoked
# Example output:
# 1) "celery:worker:state:worker1@host1:zrevoked"
# 2) "celery:worker:state:worker2@host2:zrevoked"
# 3) "celery:worker:state:worker3@host3:zrevoked"
# Check revoked tasks for a specific worker
GET celery:worker:state:worker1@host1:zrevoked
Common Issues
Issue: Workers overwriting each other's state
- Cause: Multiple workers using the same hostname
- Solution: Set unique hostnames with
-noption (e.g.,-n worker1@%h,-n worker2@%h)
Issue: DuplicateNodenameWarning on worker startup
- Cause: Another worker with the same nodename is already registered
- Solution: Ensure each worker has a unique hostname
Issue: State not persisting across restarts
- Cause: Worker hostname changes between restarts
- Solution: In containers, use stable hostnames or set custom static names
Testing
# Quick check - run all quality checks at once
make check-all
# Individual commands
make test # Run tests with coverage
make lint # Run ruff linter
make typecheck # Run mypy and ty type checkers
make format # Format code with ruff
make clean # Clean up temporary files
# Or run commands directly
uv run pytest --cov=celery_redis_statedb
uv run ruff check celery_redis_statedb/
uv run mypy celery_redis_statedb/
uv run ty check celery_redis_statedb/
Documentation
For detailed information about Celery's state persistence format and how this package implements it:
- Celery Shelve Format Documentation - Comprehensive guide to what Celery stores in its state database
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file celery_redis_statedb-0.1.0.tar.gz.
File metadata
- Download URL: celery_redis_statedb-0.1.0.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0eaf20f534f1f1765754eca0690fcb52c5ad01453a7d30283516b79c561b73f8
|
|
| MD5 |
43cbe133c6f8b03b61ce05f66f1fbcf2
|
|
| BLAKE2b-256 |
462ad97baa51fe23b313297f30ce4ad910c8e9704d23ae61e9627b151d4d8d5e
|
File details
Details for the file celery_redis_statedb-0.1.0-py3-none-any.whl.
File metadata
- Download URL: celery_redis_statedb-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b36090e1129d0105268b0b36fb248bde627885deda23c120809fb954b57f023
|
|
| MD5 |
69572bc7b657f6e317327bcd2d5f5fd0
|
|
| BLAKE2b-256 |
e45cb414bfcec2a0aa3fc16d827d74498aca1bf8d95e651ab257d97f450af8e4
|