Why You Need PgBouncer
PostgreSQL uses about 5–10MB of memory per connection. When hundreds of app connections open at once:
- Memory pressure
- Context-switching overhead
- Hitting the connection limit (
max_connections)
PgBouncer sits between the app and the database and reuses connections (pooling).
Installation
# Ubuntu / Debian
sudo apt install -y pgbouncer
# check
sudo systemctl status pgbouncerChoosing a Pooling Mode
| Mode | Description | When to use |
|---|---|---|
| session | Holds a connection for the entire client session | When using SET commands or temporary tables |
| transaction | Assigns a connection only for the duration of a transaction | Most web apps (recommended) |
| statement | Assigns a connection for a single query | Simple queries with no transactions |
pgbouncer.ini Configuration
# /etc/pgbouncer/pgbouncer.ini
[databases]
; =
myapp = host=127.0.0.1 port=5432 dbname=myapp
;
myapp_prod = host=db.example.com port=5432 dbname=myapp
[pgbouncer]
listen_addr = 127.0.0.1 ; (external when 0.0.0.0)
listen_port = 6432 ; PgBouncer
auth_type = md5 ; method
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction ;
max_client_conn = 1000 ;
default_pool_size = 25 ; DB
min_pool_size = 5
reserve_pool_size = 5
;
logfile = /var/log/postgresql/pgbouncer.log
pidfile = /var/run/postgresql/pgbouncer.pid
;
server_idle_timeout = 600
client_idle_timeout = 0
query_timeout = 0
;
admin_users = postgres
stats_users = monitorUser Authentication
# userlist.txt : "User" " when"
# PostgreSQL when
sudo -u postgres psql -c "SELECT usename, passwd FROM pg_shadow WHERE usename = 'appuser';"
# /etc/pgbouncer/userlist.txt
echo '"appuser" "md5when"' | sudo tee /etc/pgbouncer/userlist.txt
echo '"postgres" "md5when"' | sudo tee -a /etc/pgbouncer/userlist.txt
# settings
sudo chmod 640 /etc/pgbouncer/userlist.txt
sudo chown postgres:postgres /etc/pgbouncer/userlist.txt
# when
sudo systemctl restart pgbouncerConnecting Your App Through PgBouncer
# PostgreSQL
postgresql://appuser:pass@localhost:5432/myapp
# PgBouncer
postgresql://appuser:pass@localhost:6432/myappMonitoring
# PgBouncer
psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer
#
SHOW POOLS;
# database | user | cl_active | cl_waiting | sv_active | sv_idle
#
SHOW STATS;
# list
SHOW CLIENTS;
# (DB) list
SHOW SERVERS;
# settings (pgbouncer.ini after)
RELOAD;
# quit without settings
RELOAD;Tuning Guide
; (100 when , DB max_connections=100)
pool_mode = transaction
max_client_conn = 500
default_pool_size = 20 ; PgBouncer → PostgreSQL
min_pool_size = 5
reserve_pool_size = 5Actual PostgreSQL connections = default_pool_size × number of databases
Client connections = max_client_conn
→ Handle 500 app connections with 20 database connections
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Questions & answers
Ask a question about this guide. We'll review and reply.