Redis and Valkey backends#
Redis and Valkey store queue records in a shared service and use pub/sub hints to wake workers. Choose the client that matches the service your application operates.
pip install "litestar-queues[redis]"
# or: pip install "litestar-queues[valkey]"
from litestar_queues import QueueConfig, WorkerConfig
from litestar_queues.backends.redis import RedisBackendConfig
queue_config = QueueConfig(
queue_backend=RedisBackendConfig(
url="redis://localhost:6379/0",
key_prefix="myapp:queues",
worker_wakeups=True,
),
execution_backend="local",
worker=WorkerConfig(placement="external"),
)
Use ValkeyBackendConfig from litestar_queues.backends.valkey for
Valkey. Both accept the same URL-shaped connection syntax, but Valkey uses the
Valkey client and does not require Redis as an import side effect.
Note
Performance
Install hiredis alongside redis for a compiled response parser:
pip install "redis[hiredis]", or add hiredis to your dependencies
directly. redis-py uses it automatically when it is importable; no
configuration change is required. The backend requires a client that
supports pipelines and EVAL; both redis-py and valkey-py provide this.
Typical pickup time#
On a local development machine with an idle worker already running, 95 out of 100 tasks started within about 4.3 ms with Redis and 4.6 ms with Valkey. These are useful expectations, not guarantees: network distance, machine load, task volume, and service configuration can all increase pickup time.
Payloads and key isolation#
Task arguments, keyword arguments, metadata, results, and errors must be JSON
serializable. Give each application and environment a distinct key_prefix;
do not use FLUSHALL for test cleanup on shared infrastructure.
Maintenance index upgrade#
Positive maintenance limits use versioned indexes so each run examines only
the requested number of records. A new or empty key_prefix initializes
these indexes automatically. Index version 3 includes the dispatch-repair
indexes used to revisit missing Cloud Tasks deliveries fairly.
When upgrading a populated prefix created before this release,
ordinary backend opening fails closed until the indexes are rebuilt. Stop every Redis or
Valkey queue writer using that prefix, then run the rebuild once as a
standalone script. queue_config is the configuration from the example
above:
import asyncio
async def rebuild_indexes() -> None:
backend = queue_config.get_queue_backend()
try:
rebuilt = await backend.rebuild_maintenance_indexes()
print(f"reindexed {rebuilt} queue records")
finally:
await backend.close()
asyncio.run(rebuild_indexes())
The return value is the number of queue records examined. The rebuild is
explicit, unbounded, and idempotent, so an interrupted call is safe to repeat.
Run it before opening a QueueService: entering that service would hit the
old-version guard before the rebuild could run. The rebuild invalidates the
old marker first and publishes version 3 only after rebuilding every
index. Restart the writers only after it completes.
Worker wakeups#
worker_wakeups=True publishes non-durable worker hints. Workers still poll
the stored queue state. wakeup_channel and queue key prefixes belong
to queue operations, not browser Channels.
Event history and live delivery#
Backend-managed event history is supported. You choose how long Redis or Valkey keeps history, what it backs up, and when it removes old records. The library cannot make an otherwise temporary service durable.
History becomes eligible for live delivery after the record hash and its query indexes are acknowledged. Retrying the same event ID preserves the first record and repairs missing index entries; conflicting content is rejected. This does not add an fsync or replication guarantee to the service’s own configuration. See Event history for buffering and failure behavior.
A Redis or Valkey queue backend does not automatically send events to browsers. For standalone workers or multiple web processes, configure a shared Channels backend with its own key prefix. Redis pub/sub is temporary; Redis Streams can keep a backlog. Protect stream access at the Litestar route.