database connection pooling with pgbouncer

Welcome dear reader, today you will learn how to keep your PostgreSQL database fast and stable under load using connection pooling with PgBouncer. Every visitor on a busy website opens database connections, and PostgreSQL handles each one as a full process — which can exhaust your server’s memory quickly. A connection pooler solves this elegantly, and setting one up takes only a few minutes.

At re:Software S.L., we create innovative solutions for businesses that aim to digitize their processes and routines, and optimizing database connections has been key for us to provide high quality database servers.

Table of contents

What is Connection Pooling with PgBouncer?

Opening a database connection is expensive: the server must fork a process, authenticate the user, and allocate memory — for every single connection. A PHP application might open dozens of connections at once, and PostgreSQL will keep serving each of them, even when they sit idle most of the time.

Connection pooling means keeping a small set of connections open permanently and sharing them across incoming requests. Instead of 100 connections to PostgreSQL, your applications connect to the pooler, which multiplexes them over perhaps 20 real database connections.

PgBouncer is the most popular pooler for PostgreSQL — a small, single-binary tool that adds almost no overhead. If you are unsure whether PostgreSQL is the right pick in the first place, have a read about PostgreSQL vs MySQL to compare the two engines.

How to Install PgBouncer

On Ubuntu or Debian, PgBouncer is available from the package manager:

# Install PgBouncer
sudo apt install pgbouncer

# Enable and start the service
sudo systemctl enable --now pgbouncer

How to Configure PgBouncer

The main configuration lives in /etc/pgbouncer/pgbouncer.ini. The essential settings to review are:

[databases]
# Any database name can be reached through the pooler
* = host=127.0.0.1 port=5432

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432 

# Share connections per transaction: highest savings 
pool_mode = transaction 
# Max client connections allowed into the pool 
max_client_conn = 100 default_pool_size = 20

The most important knob is pool_mode. The session mode keeps a database connection for the whole client session, while transaction mode assigns a connection only while a transaction runs — the recommended setting for most web applications.

Next, create the user list that PgBouncer authenticates against, and restart the service:

# Add your database users to the userlist
echo '"webPgUser" "CrazyPassword!"' | sudo tee -a /etc/pgbouncer/userlist.txt

# Restart to apply the changes
sudo systemctl restart pgbouncer

As with any database credential, keep this password private and use something harder to guess than the example above.

Connect Your Application to the Pool

From your application’s point of view, PgBouncer looks like a normal PostgreSQL server — just on port 6432 instead of 5432. Update your connection string, e.g. in a Laravel .env:

DB_HOST=127.0.0.1
DB_PORT=6432
DB_DATABASE=db_mywebsoftware
DB_USERNAME=webPgUser
DB_PASSWORD=CrazyPassword!

No other code changes are required — your application simply connects to the pooler, and the pooler manages the real database connections behind the scenes.

Conclusion

That’s already it to get started with connection pooling in PostgreSQL. Install PgBouncer, set pool_mode = transaction, point your application at port 6432, and your database will handle far more traffic with the same hardware. Leave a comment below if you have any questions or feedback about the content of this article.

By Editorial Team

A source code library for the open world! Find snippets and examples for popular programming languages including PHP, Javascript, Typescript, Node.js, Vue.js, and more.

Leave a Reply