iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
A database connection pool reuses open connections and limits how many requests can work against the database at once. When the pool is busy, new callers wait or time out; they do not create extra database capacity. Pooling can reduce connection churn and contain concurrency, but it will not fix slow queries or make unlimited traffic safe.
Why does my app keep hitting the database connection limit?
Opening a database connection has a cost, and repeated connection creation can consume resources and add latency. In PostgreSQL’s process-per-user model, each new client connection starts a child process. If an application creates a connection for every request and closes it afterward, bursts of traffic can produce connection storms: many clients compete for a finite set of database connections.
A pool keeps established connections available for reuse. It also provides a boundary on concurrent database work. When every connection is occupied, callers queue until a connection is free or until a configured timeout expires. AWS describes this behavior as queueing or throttling connections that cannot be served immediately.
Free tools Windows power users keep installed
One-click scans. No signup required.
Pooling manages demand; it does not increase the database’s ability to execute queries. If queries are slow, adding more connections can increase contention rather than improve throughput. Investigate query performance and database saturation alongside pool behavior.
#1 Best Overall
Which layer should own the pool?
Application-side pool
An application pool typically lives inside each process or instance. It is straightforward to add, but its total maximum grows as the application fleet scales. If each instance can open up to 20 database connections and the service scales to 10 instances, the application-side maximum is 200 connections, before counting other applications, workers, monitoring, or administrative clients.
External pooler or managed proxy
A separate pooler accepts client connections from applications and manages a smaller set of backend connections to the database. This separates the number of application clients from the number of database connections, and can queue or multiplex work. PgBouncer is self-managed software with configurable pooling modes and limits. Amazon RDS Proxy is a managed option for supported Amazon RDS and Aurora deployments; its exact behavior and availability depend on the database service and engine.
A proxy does not necessarily replace the application’s own pool. Applications still need sensible connection reuse and concurrency controls, while the external layer can impose a shared backend limit across clients. Avoid treating PgBouncer and RDS Proxy as interchangeable: they differ in operational ownership, supported environments, configuration, and compatibility behavior.
How big should my database connection pool be?
There is no universal pool size established by the cited documentation. Start with the database’s actual connection budget, measure the application’s concurrent database work, reserve capacity for other consumers, and divide the application allocation across the maximum expected fleet size.
- Find the usable database budget. Account for the database connection limit and leave room for administrative access, maintenance, monitoring, and other services.
- Measure demand. Observe peak active database work and pool wait time under representative load. A high connection count by itself does not prove that the database can usefully execute more work at once.
- Allocate across the fleet. Divide the application-side maximum by the expected maximum number of app processes or instances. Include background workers and any separate pools.
- Validate under load. Track active and idle backend connections, pool wait duration, query latency, timeouts and errors, and database CPU and memory. Adjust only when those measurements show that queueing is the bottleneck and the database has capacity.
For example, if an application has an allocation of 120 connections and may run 6 instances, an even per-instance maximum would be 20. That arithmetic is only an allocation example: it does not establish that 120 active database connections are safe or useful for a particular database.
What happens when the pool is full?
When all available connections are busy, the next request waits for one to become free. A queue can absorb short bursts, but if demand stays above the rate at which queries finish, the queue grows until callers time out or fail. Set and monitor acquisition and query timeouts so the application’s overload behavior is explicit, rather than allowing requests to wait indefinitely.
With an external pooler, client limits and backend limits are distinct. PgBouncer can accept more client connections than it maintains server connections; the difference is a potential waiting population, not extra database capacity. Amazon RDS Proxy similarly has client connections and backend database connections, and exposes a borrow timeout for cases where no backend is available.
Recommended Free Tools
Increasing the client cap can require more operating-system file descriptors on a self-managed PgBouncer host. A larger client limit should therefore be paired with checks on host resources, backend capacity, and queue latency.
Rank #3
How do PgBouncer limits and pooling modes work?
PgBouncer’s configuration distinguishes client connections from server connections. Its documentation lists a default max_client_conn of 100 and a default per-user/database default_pool_size of 20. These are software defaults, not recommendations; confirm the defaults for the version you deploy.
max_client_connlimits incoming client connections.default_pool_sizecontrols the default number of server connections in a user/database pool.max_db_connectionsandmax_user_connectionsprovide additional server-side connection controls.
Use the current PgBouncer configuration documentation to verify exact settings and version behavior. The number of client slots can exceed server capacity, allowing callers to wait for backend connections, but the server-side controls must still fit the database budget.
Choose a mode that matches application semantics
- Session pooling: a client holds its server connection for the duration of its session.
- Transaction pooling: a server connection can be reused after a transaction ends.
- Statement pooling: a server connection can be reused after a statement; this mode does not permit multi-statement transactions.
Transaction and statement modes can increase backend reuse, but they change assumptions about persistent session state. Before selecting one, check the current PgBouncer feature compatibility documentation against the application’s use of prepared statements, session variables, temporary objects, and transaction boundaries.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Does a connection proxy replace a pool in my app?
Not automatically. An application pool governs connections and concurrency within each app process; a shared proxy can coordinate backend connections across multiple clients. Keeping both layers can be appropriate, but their limits and timeouts need to be aligned. If an application pool can create far more client connections than the proxy or database can serve, the queue simply moves downstream.
For Amazon RDS Proxy specifically, AWS documents a maximum backend connection limit as a percentage of the database’s max_connections. Its guidance recommends at least 30% headroom over maximum recent monitored usage. AWS also documents a default borrow timeout of 120 seconds and a maximum client connection lifetime of 24 hours. These are service-specific documented values, not general pool settings; verify current AWS documentation before deploying because service behavior can change.
AWS notes that reaching the configured backend limit can raise query latency and the DatabaseConnectionsBorrowLatency metric. For the AWS-specific details, see RDS Proxy connections and RDS Proxy pinning.
Why might a proxy fail to reuse backend connections?
Multiplexing works only when a backend connection can safely serve another client. Session state or connection-reset behavior can force a proxy to keep a client attached to one backend for the session—a behavior AWS calls pinning. Per-tenant database layouts and driver behavior can also reduce reuse.
AWS specifically warns that PostgreSQL clients using DISCARD ALL can cause pinning with RDS Proxy. If proxy backend usage is unexpectedly high, inspect proxy metrics and logs, review session-state and reset behavior, and align application and proxy idle and lifetime settings. These are RDS Proxy-specific considerations, not universal PgBouncer rules.
How should I choose between an application pool, PgBouncer, and a managed proxy?
| Option | Scope and control | Key trade-off |
|---|---|---|
| Application pool | Per process or instance; caps that process’s concurrent connections. | Simple to own, but aggregate capacity rises with fleet size and must be budgeted across instances. |
| PgBouncer | Separate, self-managed client and server connection controls; session, transaction, and statement modes. | Offers explicit pooling behavior, but you own deployment, availability, file-descriptor capacity, and application compatibility. |
| Amazon RDS Proxy | Managed proxy for supported Amazon RDS and Aurora deployments; client and backend connections are distinct. | Reduces proxy operations work, but is AWS-specific and session pinning or service limits can affect multiplexing. |
Choose based on where you need a shared limit, who will operate the component, the database host and engine, compatibility with session behavior, and how clearly you can observe queueing and timeouts. No option removes the need to budget backend connections and measure the workload.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

