redis/redis-py · error · MaxConnectionsError

Too many connections

Error message

Too many connections

What it means

Raised as MaxConnectionsError (a ConnectionError subclass, exceptions.py:282-288) by ConnectionPool.make_connection (connection.py:3318-3321) when the number of connections already created (_created_connections) has reached max_connections and a new one is requested. This is client-side pool exhaustion — the cap was hit, not a server refusal.

Source

Thrown at redis/connection.py:3321

                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 da03cdc7e8)

Solutions

  1. Raise max_connections to match your real concurrency: redis.ConnectionPool(max_connections=200).
  2. Use BlockingConnectionPool if you want callers to wait for a free connection instead of failing immediately.
  3. Audit for connection leaks — ensure every borrowed connection is released; prefer the high-level client/pipeline API which manages release automatically.
  4. Avoid holding connections across long blocking commands; use dedicated connections for MONITOR/blocking ops.

Example fix

# before
pool = redis.ConnectionPool(max_connections=10)
# 11th concurrent op raises MaxConnectionsError: Too many connections

# after
pool = redis.BlockingConnectionPool(max_connections=50, timeout=5)
# callers wait up to 5s for a free connection instead of failing
Defensive patterns

Strategy: retry

Validate before calling

def pool_with_headroom(estimated_concurrency: int) -> redis.ConnectionPool:
    cap = max(estimated_concurrency * 2, 50)
    return redis.ConnectionPool(max_connections=cap)

client = redis.Redis(connection_pool=pool_with_headroom(my_thread_count))

Try / catch

from redis.exceptions import MaxConnectionsError
for _ in range(3):
    try:
        return client.get("k")
    except MaxConnectionsError:
        time.sleep(0.2)
raise MaxConnectionsError("pool exhausted after retries")

Prevention

When it happens

Trigger: Issuing more concurrent operations than max_connections allows with the default (non-blocking) ConnectionPool, or leaking connections (failing to release them) until the cap is reached. Each get_connection that finds no free connection calls make_connection, which raises when the cap is exceeded.

Common situations: High-concurrency workloads with max_connections set too low; connection leaks from unhandled exceptions in pipeline/transaction code; long-running blocking commands (BLPOP, MONITOR) tying up connections; forking without _checkpid reset; threads each opening many connections.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/57046e591828e1bb.json. Report an issue: GitHub.