Key idea
Every open connection costs the database memory and attention, even while it sits idle. Past its limit the database refuses new connections, and every app that shares it fails at once. Size pools so that everything that connects adds up to less than the limit.
Lesson 1.9.3 introduced pools and the limit. This lesson is about why the limit exists, and how to stay under it once your app runs as several copies.
Why connections are expensive
PostgreSQL starts a separate process for each connection, with its own memory. Other databases differ in the details, but none give connections away free. A few hundred connections can use more memory than the queries themselves.
More connections also don't mean more work done. A database server has a handful of CPU cores; beyond a few busy queries per core, extra ones just wait for each other and every query gets slower. That's why the limit exists, and why raising it rarely fixes anything.
What running out looks like
At the limit, new connections are refused: sorry, too many clients already. The database is healthy, but it can't take one more.
The damage spreads. Your web service, your background worker, tonight's cron job, a migration and your own SQL console all share one limit. One service with an oversized pool can lock every other out, including you, just when you need to look inside.
A pool keeps it in hand
A pool caps how many connections one copy of your app can open. When all of them are busy, the next query waits a moment in the app for one to come back, instead of queuing inside the database.
That's why a small pool is often faster than a large one. Two settings matter:
- Maximum size: the most connections this copy opens.
- Wait timeout: how long a query waits for a free connection before failing with a clear error.
A connection that's borrowed and never returned, say because an error skipped the code that hands it back, is a leak. Leak enough and the pool empties; every request then waits, then fails.
The spherelet budget
A spherelet is one running copy of your service, and each spherelet runs its own pool. So the sum is:
spherelets × pool size + every other service's connections + a few spare ≤ the limit
Two things raise the count on the left without warning:
- Scaling up. Going from 2 spherelets to 5 multiplies that service's connections by 2.5.
- Deploys. During a rolling update, a new spherelet starts before an old one stops, so you briefly run one more than your count (lesson 5.7.2).
Check yourself