Psycopg Connection Pool
psycopg-pool provides efficient connection pooling implementations for Psycopg 3, the PostgreSQL adapter for Python. It includes both synchronous (`ConnectionPool`) and asynchronous (`AsyncConnectionPool`) pools, designed to manage a limited number of PostgreSQL connections, reduce connection overhead, and optimize resource usage in multi-threaded or async applications. The current version is 3.3.0, and it follows an independent release cycle from the main `psycopg` package.
Common errors
-
psycopg_pool.PoolTimeout: couldn't get a connection after X.X sec
cause The application requested a connection from the pool, but all connections were in use, and no new connections could be created within the configured timeout or max_size limit, often due to connection leaks, long-running transactions, or an undersized pool.fixEnsure connections are always returned to the pool using context managers (`with pool.connection() as conn:`). Increase `max_size` if more concurrent connections are needed, consider shortening transaction times, and implement `pool.check()` or `pool.close()` followed by re-opening the pool in error handling for persistent issues. -
psycopg.InterfaceError: connection already closed
cause The application attempted to use a database connection that had already been closed, typically due to idle timeouts enforced by the database server, network disruptions, or improper connection management, especially in multi-process environments.fixUtilize `psycopg-pool`'s connection context manager (`with pool.connection() as conn:`) to ensure proper connection lifecycle management. Configure `max_lifetime` in the pool to proactively recycle connections, and consider using the `check` callback or `pool.check()` to validate connection health upon retrieval. -
psycopg.OperationalError: fe_sendauth: no password supplied
cause The PostgreSQL server rejected the connection attempt because the client did not provide a password, or the provided password was incorrect, or the `pg_hba.conf` on the server is not configured to allow the specified user and host to connect without a password.fixEnsure the `conninfo` string or `kwargs` passed to `ConnectionPool` or `AsyncConnectionPool` includes the correct `password` parameter. Verify the `user` and `password` credentials and confirm the PostgreSQL server's `pg_hba.conf` configuration allows authentication for the connecting user and host. -
ModuleNotFoundError: No module named 'psycopg_pool'
cause The `psycopg_pool` package has not been installed or is not accessible in the current Python environment, as it is distributed separately from the main `psycopg` package.fixInstall the package using pip: `pip install psycopg-pool` or, if you're installing `psycopg` and want the pool as an extra, `pip install "psycopg[pool]"`.
Warnings
- breaking The default value for the `open` parameter in `ConnectionPool` is currently `True`, but this will likely change to `False` in future releases. For `AsyncConnectionPool`, opening in the constructor will become an error. Explicitly set `open=True` if you rely on the pool opening immediately, or manage it with `pool.open()` and `pool.close()` or as a context manager.
- gotcha Unlike `psycopg2`, using `with connection:` in `psycopg-pool` (via `with pool.connection() as conn:`) manages the entire connection's lifecycle within the `with` block, including returning it to the pool and implicitly handling transaction commit/rollback. In `psycopg2`, `with connection:` only managed the transaction.
- gotcha For integration with SQLAlchemy, `psycopg-pool` versions prior to 3.3.0 might behave unexpectedly if `conn.close()` is called, as it would actually close the connection instead of returning it to the pool. SQLAlchemy expects `close()` to return the connection to the pool.
- gotcha The `psycopg-pool` library has its own versioning and release cycle, which is separate from the main `psycopg` package. This is important for managing dependencies and understanding compatibility.
- gotcha Setting both `min_size` and `max_size` to 0 in `ConnectionPool` previously resulted in a hang. Since version 3.0.3, this now correctly raises a `ValueError`.
- breaking `psycopg-pool` depends on `psycopg`, which requires the PostgreSQL client library (`libpq`) to be installed in the environment. If `libpq` or its development headers are missing, `psycopg` will fail to import with an `ImportError: no pq wrapper available`, making `psycopg-pool` unusable.
- breaking `psycopg`, a dependency of `psycopg-pool`, requires the PostgreSQL client library (`libpq`) to be installed in the environment. In minimal environments (e.g., Alpine Linux), this library might be missing, leading to an `ImportError: no pq wrapper available.` when importing `psycopg`.
Install
-
pip install psycopg-pool -
pip install "psycopg[pool]"
Imports
- ConnectionPool
from psycopg_pool import ConnectionPool
- AsyncConnectionPool
from psycopg_pool import AsyncConnectionPool
- SimpleConnectionPool
from psycopg2.pool import SimpleConnectionPool
Quickstart
import os
from psycopg_pool import ConnectionPool
# Get connection string from environment variable for security
DB_URL = os.environ.get('DATABASE_URL', 'postgresql://user:password@host:port/dbname')
# Create a connection pool as a context manager
# The pool is opened and closed automatically
with ConnectionPool(DB_URL, min_size=1, max_size=5) as pool:
print("Connection pool created.")
# Get a connection from the pool as a context manager
with pool.connection() as conn:
# The connection context handles transaction commit/rollback
# and returns the connection to the pool.
with conn.cursor() as cur:
cur.execute("SELECT 1 + 1")
result = cur.fetchone()
print(f"Result: {result[0]}")
# Example of getting multiple connections (will block if pool exhausted)
print("Attempting to get another connection...")
with pool.connection() as conn2:
with conn2.cursor() as cur2:
cur2.execute("SELECT 'Hello from conn2'")
result2 = cur2.fetchone()
print(f"Result from conn2: {result2[0]}")
print("Pool is closed after exiting the 'with' block.")