Connection Pool Tuning: Application Side
Database pool tuning gets attention; app-side pool tuning rarely does. Both matter; the app side is often where the real wins are.
Why app-side matters
Database pool tuning gets all the attention; app-side pool tuning rarely does. The app side is often where the real wins are; the database accepts whatever the pool sends.
- Database accepts. The DB takes connections up to its
max_connections; the pool decides how many it uses. - Pool too small. Queueing inside your service; throughput limited; threads block on connection acquisition.
- Pool too large. Starves the DB; one app monopolises the connection pool; other apps queue at the database.
- Right-sized. Matches concurrency to workload; queueing absent at typical load; the savings are throughput, not just cost.
Four numbers per app
- 1. Min connections.
- 2. Max connections.
- 3. Acquire timeout.
- 4. Idle timeout.
Per-language defaults
Each language ships pool defaults the framework author tuned for their workload. Yours is different; the defaults are a starting point, not the destination.
- Hibernate. 10/20 default; often too small for modern web workloads; tune up first.
- HikariCP. 10 default; the recommended pool for Java; tune to workload concurrency.
- psycopg2. No pool by default; use pgbouncer or SQLAlchemy connection pooling.
- Node pg. 10 default; per-process pool; multi-process apps multiply by worker count.
Metrics to watch
Three pool metrics tell you whether tuning is working. Without them, you are tuning blind.
- Pool used / max ratio. Trending high means pool too small; trending low means pool too large.
- Acquire wait time p99. Above 100ms means contention; throughput limited by pool acquisition, not query.
- Connection age. Old connections may be stale; idle timeout tuning prevents stale-connection failures.
- Diagnostic. Pool flat at max plus high acquire wait equals throughput bottleneck; raise max or shed load.
Antipatterns
- Default pool forever. Misses workload.
- No metrics. Discovery via incident.
- Pool size = max DB connections / 1. Ignores other apps.
What to do this week
Three moves. (1) Apply this pattern to your slowest production endpoint. (2) Measure p99 before/after. (3) Document the win and ship the runbook so the team can reproduce.