Pool settings decide whether your app survives database restarts, idle timeouts and traffic spikes.
An Engine keeps a pool of DBAPI connections so each request doesn't pay to connect. The default for most databases is QueuePool:
pool_size=5: connections kept open.max_overflow=10: extra connections allowed under load, closed when returned.pool_timeout=30: seconds to wait for a free connection before raisingTimeoutError, which usually means sessions are being held too long or leaked.pool_pre_ping=True: test a connection with a lightweight ping on checkout and replace it if the server dropped it (after a restart or failover). Cheap insurance; recommended.pool_recycle=1800: replace connections older than this many seconds, for servers or proxies that kill idle connections (MySQL'swait_timeout, cloud load balancers).
Size the pool against the database's connection limit: (pool_size + max_overflow) x processes must fit. With many processes or serverless functions, use an external pooler like PgBouncer and poolclass=NullPool in the app.
Forking: connections must not cross process boundaries. With multiprocessing or pre-fork servers (Gunicorn, Celery prefork), create the engine after the fork, or call engine.dispose(close=False) in the child so it starts with a fresh pool.
engine.pool.status() shows checked-in and checked-out counts, handy when debugging exhaustion.
Example
from sqlalchemy import create_engine, text
from sqlalchemy.pool import QueuePool
engine = create_engine(
"sqlite:///app.db",
poolclass=QueuePool, # explicit here; the default for server databases
pool_size=5,
max_overflow=10,
pool_timeout=30,
pool_pre_ping=True, # replace dead connections transparently
pool_recycle=1800, # recycle connections older than 30 minutes
)
with engine.connect() as conn:
conn.execute(text("SELECT 1"))
print(engine.pool.checkedout()) # 1
print(engine.pool.checkedout()) # 0: returned to the pool
print(engine.pool.status())
# Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0Remember
- pool_size + max_overflow bound concurrent connections per process
- pool_pre_ping handles connections dropped by the server
- pool_recycle beats idle-connection timeouts
- After fork, dispose the inherited pool or create the engine in the child
Watch out for
- Sharing an engine's pooled connections between a parent and forked worker processes.