Home → Articles → How to Optimize PostgreSQL Connection Pooling with PgBouncer on Ubuntu 24.04

How to Optimize PostgreSQL Connection Pooling with PgBouncer on Ubuntu 24.04

13 Apr, 2026

Introduction

PostgreSQL creates a new server process for each client connection, which consumes significant memory and CPU resources when handling hundreds or thousands of concurrent connections. PgBouncer is a lightweight connection pooler for PostgreSQL that manages a small pool of database connections and reuses them across multiple client requests. The tool reduces the overhead of establishing new connections, lowers memory consumption, and improves overall database performance for applications with high traffic. PgBouncer supports three pooling modes including session pooling, transaction pooling, and statement pooling, each suited for different application patterns.

This guide shows you how to install and configure PgBouncer for PostgreSQL connection pooling on Ubuntu 24.04.

Prerequisites

Before you start:

Install PgBouncer from Ubuntu Repository

The PgBouncer package is available in the default Ubuntu repositories. Installing from the official repository provides a stable version tested for Ubuntu compatibility.

Configure PostgreSQL for PgBouncer Connections

PostgreSQL requires specific authentication settings to work properly with PgBouncer. You need to modify the PostgreSQL configuration to accept connections from the PgBouncer service.

Configure PgBouncer

The main PgBouncer configuration file controls database connections, pooling behavior, and authentication settings. You need to define your PostgreSQL database as a connection target and set appropriate pool sizes.

Create PgBouncer User Authentication File

PgBouncer maintains its own user authentication file separate from PostgreSQL. You need to add database users to this file with their encrypted passwords.

Manage PgBouncer Service

PgBouncer runs as a system service on Ubuntu under the name pgbouncer. You can manage this service using specific commands to start, stop, restart, and check the PgBouncer status.

Start PgBouncer Service

console
$ sudo systemctl start pgbouncer

Enable PgBouncer to Start on Boot

console
$ sudo systemctl enable pgbouncer

Output:

console
Synchronizing state of pgbouncer.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable pgbouncer

Restart PgBouncer Service

console
$ sudo systemctl restart pgbouncer

Verify PgBouncer is Running

console
$ sudo systemctl status pgbouncer

Output:

console
● pgbouncer.service - PgBouncer - lightweight connection pooler for PostgreSQL
     Loaded: loaded (/usr/lib/systemd/system/pgbouncer.service; enabled; preset: disabled)
     Active: active (running) since Wed 2026-03-15 09:45:22 UTC; 30s ago
       Docs: man:pgbouncer(1)
   Main PID: 12456 (pgbouncer)
      Tasks: 7 (limit: 2271)
     Memory: 2.5M (peak: 3.1M)
        CPU: 45ms
     CGroup: /system.slice/pgbouncer.service
             └─12456 /usr/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini

Test PgBouncer Connection

Before integrating with your application, test that PgBouncer correctly proxies connections to PostgreSQL.

PgBouncer Connection Methods for Popular Programming Languages

PgBouncer works seamlessly with any programming language that supports PostgreSQL connections. You only need to change the port from the default PostgreSQL port 5432 to the PgBouncer port 6432. The connection code remains the same in all other aspects. The examples below show how to connect to PgBouncer using Python, Go, and Node.js.

Python
import psycopg2

conn = psycopg2.connect(
    host="localhost",
    port=6432,
    database="your_database",
    user="your_database_user",
    password="your_password"
)

cur = conn.cursor()
cur.execute("SELECT version();")
version = cur.fetchone()
print(version)

cur.close()
conn.close()
Go
package main

import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/lib/pq"
)

func main() {

    connStr := "host=localhost port=6432 dbname=your_database user=your_database_user password=your_password sslmode=disable"

    db, err := sql.Open("postgres", connStr)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    var version string
    err = db.QueryRow("SELECT version();").Scan(&version)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(version)
}
JavaScript
const { Client } = require('pg');

const client = new Client({
    host: 'localhost',
    port: 6432,
    database: 'your_database',
    user: 'your_database_user',
    password: 'your_password'
});

async function connectAndQuery() {
    try {
        await client.connect();
        const res = await client.query('SELECT version();');
        console.log(res.rows[0]);
    } catch (err) {
        console.error(err);
    } finally {
        await client.end();
    }
}

connectAndQuery();

Monitor PgBouncer Statistics

PgBouncer provides a built-in admin console for monitoring connection pools, request rates, and performance metrics.

Conclusion

You installed PgBouncer on Ubuntu 24.04 and configured PostgreSQL authentication for pooled connections. You then set up pool settings including max_client_conn and default_pool_size, created the userlist file, and tested the connection through port 6432. After implementing PgBouncer, your PostgreSQL database can now handle hundreds of concurrent connections with reduced memory usage. With a ready optimized connection, you can now connect your database to your application such as Fast API.

PgBouncer FAQs for Connection Pooling

What is PgBouncer used for?

PgBouncer reduces the number of connections PostgreSQL has to handle. It takes many client connections and pools them into a few server connections, saving memory and CPU resources.

What port does PgBouncer listen on?

PgBouncer listens on port 6432 by default. PostgreSQL listens on port 5432. Your application must connect to port 6432 to use the connection pooler.

How do I restart PgBouncer after changing settings?

Run sudo systemctl restart pgbouncer to restart the service. For a safer reload that does not drop active connections, run sudo systemctl reload pgbouncer instead.

Where does PgBouncer store its configuration files?

The main configuration file is located at /etc/pgbouncer/pgbouncer.ini. The user authentication file is located at /etc/pgbouncer/userlist.txt. Both files require postgres as the owner.

How do I check if PgBouncer is running correctly?

Run sudo systemctl status pgbouncer to see the service status. You can also run psql -h localhost -p 6432 -U your_user -d pgbouncer and type SHOW STATS; to view live statistics.

Can I use PgBouncer with PostgreSQL on a different server?

Yes. Change the host value in the [databases] section from 127.0.0.1 to the remote PostgreSQL server's IP address. Ensure both servers can communicate over the network.