Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected
How-tos

Why Your Database Connection Pool Is Too Large (And How to Fix It)

Increasing your database connection pool size often reduces performance instead of improving it. Learn why queueing theory and real-world examples show that smaller pools lead to better throughput, and get a step-by-step guide to tuning your pool correctly.

June 2026 7 min read 1 views 0 hearts

You have to set a maximum connection pool size for your database. The default ten or twenty feels safe. So you bump it to fifty. Then to a hundred. And then your database falls over. Every time.

Connection pool sizing is somehow both overthought and wildly misunderstood. Engineers tweak it like a superstitious ritual instead of treating it like a queueing theory problem. The result is a generation of production systems that are either starving for connections or drowning in them.

The Single Biggest Mistake: Bigger Is Not Better

Intuition says: more connections = more throughput. Reality says: more connections = more contention.

Database connections are not free. Each one consumes memory (often 1–5 MB on the server side). Each one also holds locks, open transactions, and transaction log space. If you have 200 connections all trying to write to the same table, you haven’t scaled up — you’ve created a concurrency bottleneck that turns your database into a bouncer at a packed club.

The PostgreSQL and MySQL official docs both recommend a pool size somewhere between (2 * core_count) + effective_spindle_count. For most modern servers, that means between 10 and 30 connections — not hundreds.

The Queueing Theory Nobody Talks About

This isn’t guesswork. It’s textbook M/M/c queue behavior.

When your pool is too small, requests wait in line. That's fine — they queue at the app side, not the database side. When your pool is too large, requests still queue, but now they queue inside the database, competing for CPU, I/O, and locks. The database spends more time context-switching between connections than actually executing queries.

The sweet spot is when the database is kept busy at roughly 70–80% utilization. Past that, latency curves become exponential. Past 90%? You’re in the danger zone where a single slow query can domino into a full outage.

Real-World Example That Will Hurt You

A fintech app I consulted for had a connection pool of 150. Their database server had 8 cores and an SSD array. The app was constantly hitting 500s. The DB CPU was at 95%, but throughput was terrible.

We cut the pool to 25. The app team panicked. "We'll lose requests!"

The result: CPU dropped to 60%. Latency dropped by 40%. Throughput increased. Because the database stopped fighting itself and actually processed queries in parallel efficiently.

The queue just moved from the DB to the connection pool — where it belonged.

How to Actually Tune Your Pool

Stop guessing. Start measuring.

  1. Know your database's max concurrent capacity. Run a benchmark on your actual workload. Monitor the point where latency starts spiking as you add connections.

  2. Set pool size to that "knee" value. Not the max your app can theoretically use. Not the max the DB vendor advertises. The actual sustainable concurrent throughput.

  3. Add a queue on the app side. Almost all connection pool libraries (HikariCP, SQLAlchemy pool, Django's database pool) support a max_wait or timeout. Use it. Let your app gracefully reject requests instead of hammering the database.

  4. Monitor active connections vs idle ones. If your average active connections is 5 out of a pool of 50, your pool is too large. You’re just reserving memory nobody uses.

  5. Consider separate pools for read and write workloads. Write connections need more careful sizing because of locks. Reads are cheaper and can often use a larger pool — but still not multiplied like rabbits.

The Real Lever Is in Your App, Not Your DB

Here’s the uncomfortable truth: if you need 100+ database connections to serve acceptable throughput, your queries are too slow. Or your data access pattern is wildly inefficient. Or you’re holding connections open while doing slow I/O (like remote API calls).

Hot take: connection pool sizing is a diagnostic tool. If you can’t make your system work with 20–30 connections, you haven’t found the real bottleneck yet. You’re just applying a bandage.

Fix the queries. Add caching. Use read replicas. Then dial in your pool size as a final polish — not as your primary performance lever.

Pool sizing is misunderstood because it feels like a simple knob. It's not. It's a reflection of how well your entire system respects the database as a shared, finite resource. Treat it that way, and your production pager will finally stop screaming.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.