Jump to solution
Verify

The Fix

pip install redis==7.1.0

Based on closed redis/redis-py issue #906 · PR/commit linked

Production note: This tends to surface only under concurrency. Reproduce with load tests and watch for lock contention/cancellation paths.

Jump to Verify Open PR/Commit
@@ -20,6 +20,14 @@ * Slightly optimized command packing. Thanks @Deneby67. #1255 * Added support for the TYPE argument to SCAN. Thanks @netocp. #1220 + * Better thread and fork safety in ConnectionPool and + BlockingConnectionPool. Added better locking to synchronize critical + sections rather than relying on CPython-specific implementation details
repro.py
# simplified version ... self.session = CachedSession( backend="redis", cache_name=cache_name, allowable_codes=(200, 201), allowable_methods=("GET", "POST") ) # ... reqs = (grequests.post(url, session=self.session, auth=self.AUTH, json=data, timeout=self.TIMEOUT) for url in urls) resps = grequests.map(reqs)
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Upgrade to fixed release\npip install redis==7.1.0\nWhen NOT to use: This fix should not be used in single-threaded applications where thread safety is not a concern.\n\n

Why This Fix Works in Production

  • Trigger: the only using of lock is the reset() method, but this method is for checking the change of pid, but not the id of thread.
  • Mechanism: The connection pool's internal state is not thread-safe, leading to potential over-creation of connections
  • Why the fix works: Implements better thread safety for ConnectionPool, addressing issues with connection handling in multi-threaded environments. (first fixed release: 7.1.0).
Production impact:
  • If left unfixed, failures can be intermittent under concurrency (hard to reproduce; shows up as sporadic 5xx/timeouts).

Why This Breaks in Prod

  • The connection pool's internal state is not thread-safe, leading to potential over-creation of connections
  • Production symptom (often without a traceback): the only using of lock is the reset() method, but this method is for checking the change of pid, but not the id of thread.

Proof / Evidence

  • GitHub issue: #906
  • Fix PR: https://github.com/redis/redis-py/pull/1270
  • First fixed release: 7.1.0
  • Reproduced locally: No (not executed)
  • Last verified: 2026-02-09
  • Confidence: 0.85
  • Did this fix it?: Yes (upstream fix exists)
  • Own content ratio: 0.65

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“Are you taking into account the GIL when you are looking at the code?”
@rolette · 2017-10-26 · source
“@rolette GIL cannot guarantee of list's threading safety”
@wynemo · 2019-11-04 · source
“Hi there”
@gerazenobi · 2019-12-02 · source

Failure Signature (Search String)

  • the only using of lock is the reset() method, but this method is for checking the change of pid, but not the id of thread.
Copy-friendly signature
signature.txt
Failure Signature ----------------- the only using of lock is the reset() method, but this method is for checking the change of pid, but not the id of thread. @rolette GIL cannot guarantee of list's threading safety.

Error Message

Signature-only (no traceback captured)
error.txt
Error Message ------------- the only using of lock is the reset() method, but this method is for checking the change of pid, but not the id of thread. @rolette GIL cannot guarantee of list's threading safety.

Minimal Reproduction

repro.py
# simplified version ... self.session = CachedSession( backend="redis", cache_name=cache_name, allowable_codes=(200, 201), allowable_methods=("GET", "POST") ) # ... reqs = (grequests.post(url, session=self.session, auth=self.AUTH, json=data, timeout=self.TIMEOUT) for url in urls) resps = grequests.map(reqs)

What Broke

In multi-threaded environments, the connection pool may exceed the maximum connections limit, causing connection errors.

Why It Broke

The connection pool's internal state is not thread-safe, leading to potential over-creation of connections

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

pip install redis==7.1.0

When NOT to use: This fix should not be used in single-threaded applications where thread safety is not a concern.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Fix reference: https://github.com/redis/redis-py/pull/1270

First fixed release: 7.1.0

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • This fix should not be used in single-threaded applications where thread safety is not a concern.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Add a stress test that runs high-concurrency workloads and fails on thread dumps / blocked locks.
  • Enable watchdog dumps in prod (faulthandler, thread dump endpoint) to capture deadlocks quickly.
  • Track RSS + object counts after deployments; alert on monotonic growth and GC pressure.
  • Add a long-running test that repeats the failing call path and asserts stable memory.

Version Compatibility Table

VersionStatus
7.1.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.