redis/redis-py · error · MaxConnectionsError
Too many connections
Error message
Too many connections
What it means
Raised as MaxConnectionsError('Too many connections') by ConnectionPool.make_connection when the number of connections already created (_created_connections) has reached max_connections. MaxConnectionsError subclasses ConnectionError. This is the bounded (default) ConnectionPool refusing to open a new socket beyond its cap — it does not block; the caller sees the exception immediately.
Solutions
- Raise max_connections to match your expected concurrency.
- Ensure connections are always released — use context managers or let the client manage the pool (Redis.execute_command returns the connection automatically).
- Reduce the number of concurrently held connections (fewer pubsub listeners, shorter blocking commands, bounded thread/async pools).
- If you want blocking behaviour instead of an immediate error, use BlockingConnectionPool.
Example fix
# before pool = ConnectionPool(max_connections=10) # raises under load # after pool = ConnectionPool(max_connections=50) # or block-wait instead of erroring from redis.connection import BlockingConnectionPool pool = BlockingConnectionPool(max_connections=50, timeout=10)
Defensive patterns
Strategy: retry
Validate before calling
from redis.connection import BlockingConnectionPool
def build_pool(max_connections, blocking=True, timeout=10):
# Prefer a blocking pool if you want to wait rather than error at the cap.
cls = BlockingConnectionPool if blocking else ConnectionPool
return cls(max_connections=max_connections, timeout=timeout) if blocking else cls(max_connections=max_connections) Try / catch
import time
from redis.exceptions import MaxConnectionsError
for attempt in range(4):
try:
return r.get('key')
except MaxConnectionsError:
if attempt < 3:
time.sleep(0.1 * (2 ** attempt))
continue
raise # pool is genuinely saturated; raise so callers can shed load Prevention
- Size max_connections to your real concurrency.
- Always release connections (let the Redis client manage the pool).
- Keep blocking commands/pubsub on a separate, adequately sized pool.
- Use BlockingConnectionPool if you prefer waiting over immediate failure.
When it happens
Trigger: Borrowing more than max_connections connections concurrently from a single ConnectionPool without releasing them. Long-held connections (e.g. pubsub, blocking BLPOP, MONITOR) accumulating against a small pool. Connection leak from not releasing.
Common situations: Default max_connections=100 exceeded under heavy concurrency or due to leaked connections. Blocking commands (BLPOP, WAIT) pinning connections. Pubsub/monitor listeners holding many. Forked workers each inheriting a full pool.
Related errors
- No connection available.
- Maintenance notifications are not supported with
- "max_connections" must be a positive integer
- Argument 'db' must be 0 or None in cluster mode
- Cache must implement CacheInterface
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/57046e591828e1bb.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:3336
connection_pool=self,
duration_seconds=time.monotonic() - start_time_created,
)
return connection
def get_encoder(self) -> Encoder:
"Return an encoder based on encoding settings"
kwargs = self.connection_kwargs
return Encoder(
encoding=kwargs.get("encoding", "utf-8"),
encoding_errors=kwargs.get("encoding_errors", "strict"),
decode_responses=kwargs.get("decode_responses", False),
)
def make_connection(self) -> "ConnectionInterface":
"Create a new connection"
if self._created_connections >= self.max_connections:
raise MaxConnectionsError("Too many connections")
self._created_connections += 1
kwargs = dict(self.connection_kwargs)
# Create the connection first, then record metrics only on success
if self.cache is not None:
connection = CacheProxyConnection(
self.connection_class(**kwargs), self.cache, self._lock
)
else:
connection = self.connection_class(**kwargs)
# Record new connection created (starts as IDLE) - only after successful construction
record_connection_count(
pool_name=get_pool_name(self),
connection_state=ConnectionState.IDLE,
counter=1,
)View on GitHub (pinned to 6a6b581b48)