`max_connections` sets the number of client connections PostgreSQL will accept concurrently. A large value is not automatically better: it permits more simultaneous work, but can push a modest server into overload. Changing it requires a PostgreSQL restart. section 6.3
The tempting mistake is to raise the limit for every expected client. With `max_connections = 2000`, a pgbench run at 2,000 clients reached only 352 TPS while average latency rose to 5,535 ms. Throughput stayed broadly flat across much lower client counts, but latency did not recover until 32 clients or fewer. section 6.3
Table 6.1 Test results showing TPS and latency with various numbers of clients
|
Number of clients
|
TPS
|
Latency average
|
|---|---|---|
|
2,000
|
352.1
|
5,535.267 ms
|
|
1,500
|
506.8
|
2,869.986 ms
|
|
1,000
|
586.1
|
1,694.616 ms
|
|
500
|
628.4
|
794.688 ms
|
|
250
|
635.7
|
392.554 ms
|
|
125
|
556.9
|
224.411 ms
|
|
63
|
613.0
|
102.758 ms
|
|
32
|
572.3
|
55.907 ms
|
|
16
|
301.8
|
53.009 ms
|
Compare throughput with latency rather than treating a TPS plateau as proof that the server is healthy. The high-client runs trade response time for concurrency. section 6.3
Connection limits also interact with memory settings. `work_mem` can be allocated per execution-plan node for each running query, so allowing many sessions while using an oversized `work_mem` can create memory demand far beyond available RAM. In a stress test with 1,000 clients, `shared_buffers = 12GB` and `work_mem = 2GB`, the workload stalled and Linux's OOM killer terminated a PostgreSQL process. section 6.2
Treat a connection limit as a capacity decision:
- Test realistic client counts with pgbench, recording both TPS and average latency. section 6.3
- Size `max_connections` alongside `work_mem`, query complexity, and available RAM rather than independently. section 6.2
- Investigate severe memory pressure in system logs; the Linux OOM killer may terminate PostgreSQL or another necessary process. section 6.2
High limit, poor responsiveness
A configuration of `shared_buffers = 1GB`, `work_mem = 4MB`, and `max_connections = 2000` allowed a 2,000-client benchmark to complete, yet its 5.5-second average latency showed that accepting connections was not the same as serving them responsively. section 6.3
