Question: Connections and sessions
How many connections can Postgres handle?
Answered in the first paragraph. Last updated .
There is no single number, and the useful question is different from the one asked. A server will happily hold thousands of open connections. What it can work on simultaneously is bounded by cores and by memory, and that ceiling is usually in the low hundreds at most. Sizing the limit from the number of application threads is what produces a database that is busy and slow.
Two separate ceilings, only one of which is configurable
The configured limit is an allocation decision taken at startup: shared memory sized for that many backends, and a hard refusal beyond it.
The real ceiling is arithmetic. Each connection is an operating system process. Each running query may allocate working memory for sorts and hashes, and it may allocate that amount more than once within a single plan, which is why memory exhaustion is reached far sooner than multiplying the setting by the connection count suggests. Meanwhile the number of queries actually progressing at any instant cannot exceed what the cores and the storage can carry, so extra backends convert into queueing rather than into throughput.
A fair rule for the active number is a small multiple of the core count, arrived at by measurement rather than by formula, with the rest of the application’s concurrency absorbed by a pool. Idle connections are much cheaper than they used to be, since PostgreSQL 14 stopped making every snapshot pay attention to backends that are doing nothing, but cheap is not free and it says nothing about the active number.
What to measure before choosing a limit
Look at how many sessions are running a statement at the busiest minute of the week, not at how many are connected. The gap between those two figures is the size of the pool you should have and do not.
Then look at what the busy ones are waiting on. If they are waiting on each other rather than on storage, more connections will make the contention worse in a way that is very hard to see from the application, because every individual query looks merely slow.
Memory deserves one more thought. The database is not the only cache in the system, and a page can be resident twice, which is double buffering and is part of why a large shared buffer setting plus a large connection limit is a worse trade than it appears.
Connection pooling and PgBouncer covers the pooling modes and which one your transaction patterns can actually tolerate. The failure mode to recognise if the count climbs on its own during an incident is a connection storm.
If you would rather have the numbers than the rule, the connections and pooling calculator puts your transaction rate through Little’s law, subtracts the reservations the server holds back, and compares both against what your pools will try to open during a rolling deploy.