Measured on 0.1.3 with redis-py 8.1.0, Redis 7 in a container that I paused so that connections neither succeed nor fail. One GET per client, with socket_timeout=0.5 and socket_connect_timeout=0.5 in the pool settings and the retry group left at its defaults, then with retry.enabled=False, max_attempts=0 spelled out:
bare redis-py, defaults retry handed to redis-py: Retry retries=10 backoff=ExponentialWithJitterBackoff
bare redis-py, timeouts 0.5 + Retry(NoBackoff(), 0) retry handed to redis-py: Retry retries=0 backoff=NoBackoff
kit, timeouts 0.5, retry settings default retry handed to redis-py: Retry retries=10 backoff=ExponentialWithJitterBackoff
kit, timeouts 0.5, retry.enabled=False explicitly retry handed to redis-py: Retry retries=10 backoff=ExponentialWithJitterBackoff
--- Redis paused: one GET per client ---
bare redis-py, defaults -> still waiting 20.00 s (gave up watching)
bare redis-py, timeouts 0.5 + Retry(NoBackoff(), 0) -> TimeoutError 0.50 s
kit, timeouts 0.5, retry settings default -> TimeoutError 9.93 s
kit, timeouts 0.5, retry.enabled=False explicitly -> TimeoutError 17.90 s
Rule 5 on the agents page says that with no Retry handed to it redis-py does not retry at all. That was true once; redis-py now ships a default Retry(ExponentialWithJitterBackoff, retries=10) when retry is not given, and the kit hands nothing when retry.enabled is false, so a client configured to fail in half a second fails in ten to eighteen, jitter deciding which. For the use this post is about, a cache or an idempotency store that should fail open fast when Redis is gone, that is the difference between a request that degrades and a request that times out at the load balancer.
What I think it needs: when retries are disabled the factory should pass Retry(NoBackoff(), 0) explicitly, so "disabled" means what it says whatever redis-py's default is; when they are enabled, the kit's Retry is already explicit. Rule 5 and the retry section of the configuration guide follow. It may be worth a second look at whether the kit's own backoff should carry jitter now that redis-py's does, but that is a separate question from the default.
Scripts: retry_probe.py in https://github.com/bedrock-python/bedrock-python.github.io/tree/docs/production-python-series/docs/blog/lab/2026-09-07-when-should-redis-fail-open.
Measured on 0.1.3 with redis-py 8.1.0, Redis 7 in a container that I paused so that connections neither succeed nor fail. One GET per client, with
socket_timeout=0.5andsocket_connect_timeout=0.5in the pool settings and the retry group left at its defaults, then withretry.enabled=False, max_attempts=0spelled out:Rule 5 on the agents page says that with no
Retryhanded to it redis-py does not retry at all. That was true once; redis-py now ships a defaultRetry(ExponentialWithJitterBackoff, retries=10)whenretryis not given, and the kit hands nothing whenretry.enabledis false, so a client configured to fail in half a second fails in ten to eighteen, jitter deciding which. For the use this post is about, a cache or an idempotency store that should fail open fast when Redis is gone, that is the difference between a request that degrades and a request that times out at the load balancer.What I think it needs: when retries are disabled the factory should pass
Retry(NoBackoff(), 0)explicitly, so "disabled" means what it says whatever redis-py's default is; when they are enabled, the kit'sRetryis already explicit. Rule 5 and the retry section of the configuration guide follow. It may be worth a second look at whether the kit's own backoff should carry jitter now that redis-py's does, but that is a separate question from the default.Scripts:
retry_probe.pyin https://github.com/bedrock-python/bedrock-python.github.io/tree/docs/production-python-series/docs/blog/lab/2026-09-07-when-should-redis-fail-open.