Robert Szomolanyi
02/26/2026, 6:51 PMMarvin
02/26/2026, 6:51 PMMarvin
02/26/2026, 6:54 PMREDIS_APPENDONLY=no
REDIS_SAVE=""
- Ensure all API/server replicas share the same Redis and Postgres.
Example Prefect 3.x config (self-hosted, HA):
# Durable state
PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://user:pass@postgres:5432/prefect>
# Use Redis-backed coordination for multi-replica/active-active
PREFECT_MESSAGING_BROKER=prefect_redis.messaging
PREFECT_MESSAGING_CACHE=prefect_redis.messaging
PREFECT_SERVER_EVENTS_CAUSAL_ORDERING=prefect_redis.ordering
PREFECT_SERVER_CONCURRENCY_LEASE_STORAGE=prefect_redis.lease_storage
PREFECT_SERVER_DOCKET_URL=<redis://redis:6379/1>
# Connection details for the Redis integration
PREFECT_REDIS_MESSAGING_HOST=redis
PREFECT_REDIS_MESSAGING_PORT=6379
PREFECT_REDIS_MESSAGING_DB=0
What you get with ephemeral Redis:
- Concurrency leases auto-expire and are reacquired
- Background services auto re-elect a leader
- Events in transit are reprocessed
- No durable data loss (Postgres holds it)
Follow-up questions to tailor guidance:
- Are you running multiple API/server replicas across namespaces/clusters? If so, ensure they share a single highly available Redis endpoint.
- Do you already have a managed/operated Redis in OpenShift? If yes, you can usually turn off AOF/RDB and skip PVCs safely for Prefect’s use case.Robert Szomolanyi
02/26/2026, 7:01 PMMarvin
02/26/2026, 7:01 PMMarvin
02/26/2026, 7:02 PM# Same env as your API pods for DB + Redis:
PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://user:pass@postgres:5432/prefect>
# Multi-replica/HA requires Redis-backed coordination:
PREFECT_MESSAGING_BROKER=prefect_redis.messaging
PREFECT_MESSAGING_CACHE=prefect_redis.messaging
PREFECT_SERVER_EVENTS_CAUSAL_ORDERING=prefect_redis.ordering
PREFECT_SERVER_CONCURRENCY_LEASE_STORAGE=prefect_redis.lease_storage
PREFECT_SERVER_DOCKET_URL=<redis://redis:6379/1>
# Start all enabled services in a pod:
prefect server services start
Notes and gotchas
- You do not need Redis persistence, but you do want Redis to be highly available (Sentinel/Cluster or managed) and reachable from both localities.
- Keep latencies to Redis/Postgres reasonable; services are sensitive to lock TTLs and scheduling loops.
- If you prefer extra redundancy, you can run 2 services pods per locality (total 4). It won’t harm anything—only one pod per service will be active—but typically 1 per locality is sufficient.
Questions to confirm so I can fine-tune:
- Will both localities point to the same Postgres and Redis endpoints?
- Any cross-locality latency constraints I should be aware of?Robert Szomolanyi
02/26/2026, 7:14 PMMarvin
02/26/2026, 7:14 PMMarvin
02/26/2026, 7:17 PM# Overall memory
redis-cli INFO memory | egrep 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'
# Stream sizes
redis-cli XLEN <your_event_stream_key>
redis-cli XINFO STREAM <your_event_stream_key>
redis-cli XINFO GROUPS <your_event_stream_key>
redis-cli XPENDING <your_event_stream_key> <group-name>
# Key counts by area
redis-cli --scan --pattern 'prefect:concurrency:*' | wc -l
redis-cli --scan --pattern '*:seen:*' | wc -l
redis-cli --scan --pattern 'message:*' | wc -l
2) Estimate average message size
- Take a time window (e.g., 10 minutes), record XLEN delta, and watch used_memory delta. Divide to get bytes/message. Validate your 0.5–1.0 KB assumption.
3) Tune
- If streams grow too large: increase trim frequency, reduce idle threshold for trimming, or add/accelerate consumers.
- If PEL (pending entries) grows: consumers are falling behind—scale your API/services or lower per-message processing time.
Redis configuration tips for Prefect
- Persistence: keep it off (AOF off, RDB off) to reduce memory/IO overhead:
REDIS_APPENDONLY=no
REDIS_SAVE=""
- maxmemory: set high enough to avoid evictions. If you must cap, use a policy that won’t silently drop streams (noeviction is safer operationally—you’ll see write errors rather than silent data loss).
- HA: use Sentinel or a managed HA Redis. For very large volumes, Redis Cluster can help, but be mindful a single hot stream key will live on a single shard—shard streams by topic if needed.
Concurrency/leases footprint
- Leases are tiny (≈200–400 bytes/lease plus small index entries). Even 10k concurrent leases is typically just a few MB. Most memory is driven by streams.
Practical starting points
- Most deployments: start with 512 MB–1 GB, no persistence, and short stream retention (5–15 min) with consumers keeping up.
- Higher throughput (hundreds of events/sec): 1–2 GB.
- Thousands of events/sec or long retention: 4–6 GB, or reduce retention and increase consumer throughput.Marvin
02/26/2026, 7:17 PM