redis/redis-py · error · MaxConnectionsError
Too many connections
Error message
Too many connections
What it means
Raised as MaxConnectionsError (a subclass of ConnectionError) by get_available_connection() when no idle connection is available and the number of in-use connections has reached max_connections. The pool is exhausted and cannot create a new connection. This is the non-blocking pool's hard limit; BlockingConnectionPool waits instead (see [130]).
Source
Thrown at redis/asyncio/connection.py:2844
if is_created:
await record_connection_create_time(
connection_pool=self,
duration_seconds=time.monotonic() - start_time_created,
)
return connection
except BaseException:
await self.release(connection)
raise
def get_available_connection(self):
"""Get a connection from the pool, without making sure it is connected"""
try:
connection = self._available_connections.pop()
except IndexError:
if len(self._in_use_connections) >= self.max_connections:
raise MaxConnectionsError("Too many connections") from None
connection = self.make_connection()
self._in_use_connections.add(connection)
return connection
def get_encoder(self):
"""Return an encoder based on encoding settings"""
kwargs = self.connection_kwargs
return self.encoder_class(
encoding=kwargs.get("encoding", "utf-8"),
encoding_errors=kwargs.get("encoding_errors", "strict"),
decode_responses=kwargs.get("decode_responses", False),
)
def make_connection(self):
"""Create a new connection. Can be overridden by child classes."""
# Note: We don't record IDLE here because async uses a sync make_connection
# but async record_connection_count. The recording is handled in get_connection.
return self.connection_class(**self.connection_kwargs)View on GitHub (pinned to da03cdc7e8)
Solutions
- Increase max_connections to match your real concurrency.
- Ensure every borrowed connection is released (use 'async with redis:' context or release in finally).
- Audit for leaked connections and long-held pipelines/transactions.
- Switch to BlockingConnectionPool if you want callers to wait instead of erroring.
Example fix
// before
for i in range(500):
asyncio.create_task(redis.get(f'k{i}')) # exceeds max_connections=100
// after
sem = asyncio.Semaphore(redis.connection_pool.max_connections)
async def guarded(i):
async with sem:
await redis.get(f'k{i}')
await asyncio.gather(*(guarded(i) for i in range(500))) Defensive patterns
Strategy: retry
Validate before calling
def safe_concurrency_limit(pool, tasks):
# avoid fanning out beyond the pool
return min(len(tasks), pool.max_connections)
limit = safe_concurrency_limit(redis.connection_pool, tasks)
sem = asyncio.Semaphore(limit) Type guard
def pool_saturated(pool) -> bool:
return len(pool._in_use_connections) >= pool.max_connections Try / catch
from redis.exceptions import MaxConnectionsError
try:
await redis.get('k')
except MaxConnectionsError:
await asyncio.sleep(backoff)
await redis.get('k') # retry after a connection is freed Prevention
- Set max_connections to match real concurrency.
- Always release connections (async with redis: ...).
- Bound fan-out with a Semaphore sized to max_connections.
- Switch to BlockingConnectionPool to wait instead of error.
When it happens
Trigger: Using the default (non-blocking) ConnectionPool and issuing more concurrent commands than max_connections without releasing connections first. Happens with pipelines/transactions held open, leaked connections (not released), or genuine concurrency above the limit. Fires at connection.py:2843.
Common situations: Leaking connections (e.g., a command that errors before release); long-running pipelines/transactions holding many connections; undersized max_connections for the workload; async tasks fanning out faster than connections are returned.
Related errors
- No connection available.
- Cannot disable maintenance notifications after enabling them
- Either maint_notifications_pool_handler or oss_cluster_maint
- "max_connections" must be a positive integer
- Connection has data
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/600f05615dacc0ac.json.
Report an issue: GitHub.