{"id":"1cf9cc85fb62999f","repo":"psycopg/psycopg2","slug":"connection-pool-exhausted","errorCode":null,"errorMessage":"connection pool exhausted","messagePattern":"connection pool exhausted","errorType":"exception","errorClass":"PoolError","httpStatus":null,"severity":"error","filePath":"lib/pool.py","lineNumber":92,"sourceCode":"        return self._keys\n\n    def _getconn(self, key=None):\n        \"\"\"Get a free connection and assign it to 'key' if not None.\"\"\"\n        if self.closed:\n            raise PoolError(\"connection pool is closed\")\n        if key is None:\n            key = self._getkey()\n\n        if key in self._used:\n            return self._used[key]\n\n        if self._pool:\n            self._used[key] = conn = self._pool.pop()\n            self._rused[id(conn)] = key\n            return conn\n        else:\n            if len(self._used) == self.maxconn:\n                raise PoolError(\"connection pool exhausted\")\n            return self._connect(key)\n\n    def _putconn(self, conn, key=None, close=False):\n        \"\"\"Put away a connection.\"\"\"\n        if self.closed:\n            raise PoolError(\"connection pool is closed\")\n\n        if key is None:\n            key = self._rused.get(id(conn))\n            if key is None:\n                raise PoolError(\"trying to put unkeyed connection\")\n\n        if len(self._pool) < self.minconn and not close:\n            # Return the connection into a consistent state before putting\n            # it back into the pool\n            if not conn.closed:\n                status = conn.info.transaction_status\n                if status == _ext.TRANSACTION_STATUS_UNKNOWN:","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/psycopg/psycopg2/blob/3a6d9d6ddc6b53eaa80b712f5fa6b23abbdc38db/lib/pool.py#L74-L110","documentation":"Raised by AbstractConnectionPool._getconn() (lib/pool.py:91-92) when the pool has no idle connections in _pool and the number of currently checked-out connections (len(_used)) has reached maxconn. The pool cannot create a new connection without exceeding its configured maximum, so it refuses the request rather than silently growing.","triggerScenarios":"Calling getconn() more than maxconn times without returning connections via putconn(). Each getconn() without a matching putconn() adds to _used; when len(_used) == maxconn and _pool is empty, this error fires.","commonSituations":"Connection leaks — code that forgets to call putconn() (e.g. an exception skips the finally block). Long-running transactions holding connections. Under-provisioned maxconn for the workload concurrency. In threaded pools, more concurrent workers than maxconn.","solutions":["Ensure every getconn() is paired with a putconn() in a try/finally block.","Raise maxconn to match peak concurrency.","Audit for connection leaks: log len(pool._used) periodically or use a context manager wrapper.","Shorten transaction lifetimes so connections return to the pool faster.","Switch to a pool that blocks/waits (or implement a semaphore) instead of failing fast if bursty traffic is expected."],"exampleFix":"// before\nconn = pool.getconn()\nuse(conn)  # exception here leaks the connection\n// after\nconn = pool.getconn()\ntry:\n    use(conn)\nfinally:\n    pool.putconn(conn)","handlingStrategy":"try-catch","validationCode":"if len(pool._used) >= pool.maxconn:\n    # pool will be exhausted; back off or raise early\n    raise RuntimeError('pool at maxconn; possible leak')","typeGuard":"def pool_has_capacity(pool) -> bool:\n    return len(pool._used) < pool.maxconn","tryCatchPattern":"from psycopg2.pool import PoolError\ntry:\n    conn = pool.getconn()\nexcept PoolError as e:\n    if 'exhausted' in str(e):\n        # retry after a short delay or reject the request\n        time.sleep(retry_delay)\n        conn = pool.getconn()\n    else: raise","preventionTips":["Always pair getconn with putconn in try/finally.","Size maxconn to peak concurrency; monitor len(pool._used).","Use a context manager that guarantees return."],"tags":["pool","resource-exhaustion","connection-leak","threading","pool-error"],"analyzedSha":"3a6d9d6ddc6b53eaa80b712f5fa6b23abbdc38db","analyzedAt":"2026-08-04T19:56:51.958Z","schemaVersion":2}