NullPool opens a connection per request and closes immediately — slow but isolated (great for tests). The default pool keeps N connections alive and reuses — fast but tests share them, so a transaction leak in one test poisons the next. Pre-ping catches dropped TCP connections; recycle prevents stale ones.
NullPool + echo=False for pytest: each test gets a fresh conn.
pool_size=N + pool_pre_ping=True for prod: reuse + drop detection.
pool_recycle=3600 prevents MySQL/Postgres from killing idle conns without telling you.
Settings.environment -> engine_kwargs
test -> NullPool, echo=False
prod -> pool_size=N, pool_pre_ping=True, pool_recycle=3600
Pick the pool once per environment, then stop touching it. The branches above are the canonical defaults.