--- title: "Cómo configurar PgBouncer para PostgreSQL en Ubuntu 24.04" description: "Instala PgBouncer en Ubuntu 24.04, configura el pooling en modo transacción con autenticación SCRAM y comprueba con pgbench cómo reutiliza las conexiones." category: "Base de Datos Avanzada" language: es source: https://cubepath.com/es/docs/base-de-datos-avanzada/agrupamiento-de-conexiones-de-base-de-datos-con-pgbouncer updated: 2026-09-25 --- # Cómo configurar PgBouncer para PostgreSQL en Ubuntu 24.04 Cada conexión a PostgreSQL crea un proceso nuevo en el servidor, con su coste de memoria y de arranque. Cuando una aplicación abre cientos de conexiones cortas, el servidor pasa más tiempo gestionándolas que ejecutando consultas. PgBouncer es un pooler ligero que se sitúa entre la aplicación y PostgreSQL y reparte muchas conexiones de clientes sobre un número pequeño de conexiones reales. En este tutorial instalarás PgBouncer en Ubuntu 24.04, lo configurarás en modo transacción con autenticación SCRAM y comprobarás con `pgbench` cómo reutiliza las conexiones. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con PostgreSQL 16 instalado y en marcha (`sudo apt install postgresql`). - Un usuario no root con privilegios `sudo`. - PostgreSQL usando `scram-sha-256` para cifrar contraseñas, que es el valor por defecto en PostgreSQL 14 y posteriores. En esta guía PgBouncer se instala en el mismo servidor que PostgreSQL. Si lo pones en otra máquina, solo cambia la dirección `host` de la sección `[databases]`. ## Paso 1: Crear la base de datos y los usuarios Crea un usuario para la aplicación y una base de datos de la que sea propietario: ```bash sudo -u postgres psql -c "CREATE ROLE appuser WITH LOGIN PASSWORD 'your_strong_password';" sudo -u postgres createdb -O appuser appdb ``` Crea también un rol para administrar PgBouncer. No necesita acceso a ninguna base de datos real, pero así PostgreSQL genera su hash SCRAM, que reutilizarás en el paso 3: ```bash sudo -u postgres psql -c "CREATE ROLE pgb_admin WITH LOGIN PASSWORD 'your_admin_password';" ``` Sustituye `your_strong_password` y `your_admin_password` por contraseñas propias. Comprueba que la aplicación puede conectarse directamente a PostgreSQL por TCP: ```bash psql -h 127.0.0.1 -U appuser -d appdb -c "SELECT current_user;" ``` ```output current_user -------------- appuser (1 row) ``` ## Paso 2: Instalar PgBouncer PgBouncer está en los repositorios de Ubuntu: ```bash sudo apt update sudo apt install pgbouncer ``` Comprueba la versión instalada: ```bash pgbouncer --version ``` ```output PgBouncer 1.22.0 ... ``` El paquete crea el servicio `pgbouncer`, que se ejecuta con el usuario `postgres`, y deja la configuración en `/etc/pgbouncer/`. ## Paso 3: Crear el archivo de usuarios PgBouncer autentica a los clientes con el archivo `userlist.txt`. Si guardas en él el hash SCRAM de cada usuario, tal y como está en PostgreSQL, PgBouncer puede validar al cliente y también iniciar sesión en PostgreSQL en su nombre sin guardar contraseñas en texto plano. Extrae los hashes: ```bash sudo -u postgres psql -Atc "SELECT '\"' || rolname || '\" \"' || rolpassword || '\"' FROM pg_authid WHERE rolname IN ('appuser', 'pgb_admin');" ``` ```output "appuser" "SCRAM-SHA-256$4096:Xb3n...$Qm8...:Zp1..." "pgb_admin" "SCRAM-SHA-256$4096:k9Td...$Wc2...:Hr7..." ``` Crea el archivo con esas dos líneas: ```bash sudo nano /etc/pgbouncer/userlist.txt ``` ```text "appuser" "SCRAM-SHA-256$4096:Xb3n...$Qm8...:Zp1..." "pgb_admin" "SCRAM-SHA-256$4096:k9Td...$Wc2...:Hr7..." ``` Solo el usuario `postgres`, que ejecuta PgBouncer, debe poder leerlo: ```bash sudo chown postgres:postgres /etc/pgbouncer/userlist.txt sudo chmod 0640 /etc/pgbouncer/userlist.txt ``` > Importante: si cambias la contraseña de un usuario en PostgreSQL, tienes que actualizar su línea en `userlist.txt` y recargar PgBouncer, o las conexiones a través del pooler fallarán. ## Paso 4: Configurar PgBouncer Haz una copia del archivo original, que está lleno de comentarios útiles como referencia: ```bash sudo cp /etc/pgbouncer/pgbouncer.ini /etc/pgbouncer/pgbouncer.ini.orig ``` Abre el archivo y reemplaza su contenido: ```bash sudo nano /etc/pgbouncer/pgbouncer.ini ``` ```ini [databases] appdb = host=127.0.0.1 port=5432 dbname=appdb [pgbouncer] listen_addr = 127.0.0.1 listen_port = 6432 unix_socket_dir = /var/run/postgresql auth_type = scram-sha-256 auth_file = /etc/pgbouncer/userlist.txt admin_users = pgb_admin pool_mode = transaction max_client_conn = 500 default_pool_size = 20 min_pool_size = 5 reserve_pool_size = 5 reserve_pool_timeout = 3 server_idle_timeout = 600 max_prepared_statements = 100 ignore_startup_parameters = extra_float_digits ``` Qué hace cada bloque: - `[databases]`: nombre que verán los clientes (`appdb`) y a qué base real apunta. - `listen_addr` y `listen_port`: PgBouncer escucha en el puerto 6432 solo en localhost. Si tus aplicaciones están en otros servidores, pon aquí la IP privada y abre el puerto en el firewall solo para esa red. - `pool_mode = transaction`: la conexión al servidor se asigna a un cliente solo durante una transacción y después vuelve al pool. Es el modo que más conexiones ahorra. - `max_client_conn`: máximo de clientes conectados a PgBouncer. `default_pool_size`: conexiones reales a PostgreSQL por cada par usuario/base de datos. - `reserve_pool_size` y `reserve_pool_timeout`: hasta 5 conexiones extra si un cliente lleva más de 3 segundos esperando. - `max_prepared_statements`: permite que los drivers que usan sentencias preparadas a nivel de protocolo funcionen en modo transacción. - `ignore_startup_parameters = extra_float_digits`: algunos drivers, como el JDBC de PostgreSQL, envían este parámetro al conectar y PgBouncer lo rechazaría. Reinicia el servicio para aplicar la configuración: ```bash sudo systemctl restart pgbouncer systemctl status pgbouncer --no-pager ``` ```output ● pgbouncer.service - connection pooler for PostgreSQL Loaded: loaded (/usr/lib/systemd/system/pgbouncer.service; enabled; preset: enabled) Active: active (running) since ... ``` Si no arranca, `sudo journalctl -u pgbouncer -n 30` muestra la línea del archivo que falla. ## Paso 5: Conectarse a través de PgBouncer Conecta a la base de datos usando el puerto 6432 en lugar del 5432: ```bash psql -h 127.0.0.1 -p 6432 -U appuser -d appdb -c "SELECT current_user, inet_server_port();" ``` ```output current_user | inet_server_port --------------+------------------ appuser | 5432 (1 row) ``` `inet_server_port()` devuelve 5432 porque la consulta la ejecuta PostgreSQL a través de una conexión del pool. En tu aplicación solo tienes que cambiar el puerto de la cadena de conexión, por ejemplo `postgresql://appuser:your_strong_password@127.0.0.1:6432/appdb`. ## Paso 6: Consultar la consola de administración PgBouncer expone una base de datos virtual llamada `pgbouncer` con comandos de administración. Conéctate con el usuario de `admin_users`: ```bash psql -h 127.0.0.1 -p 6432 -U pgb_admin pgbouncer ``` Muestra el estado de los pools: ```sql SHOW POOLS; ``` Las columnas más útiles son `cl_active` (clientes con una conexión asignada), `cl_waiting` (clientes esperando una conexión libre), `sv_active` y `sv_idle` (conexiones reales a PostgreSQL en uso y libres) y `maxwait` (segundos que lleva esperando el cliente más antiguo). Otros comandos útiles: ```sql SHOW STATS; SHOW CLIENTS; SHOW SERVERS; RELOAD; ``` `RELOAD` vuelve a leer `pgbouncer.ini` y `userlist.txt` sin cortar conexiones. Sal con `\q`. ## Paso 7: Probar el pooling con pgbench `pgbench`, incluido con PostgreSQL, permite comprobar el efecto del pooler. Inicializa sus tablas de prueba en `appdb` a través de PgBouncer: ```bash pgbench -h 127.0.0.1 -p 6432 -U appuser -i appdb ``` Lanza una prueba de solo lectura con 100 clientes simultáneos durante 30 segundos: ```bash pgbench -h 127.0.0.1 -p 6432 -U appuser -c 100 -j 4 -T 30 -S appdb ``` Mientras corre, en otra terminal ejecuta `SHOW POOLS;` en la consola de administración. Verás 100 clientes (`cl_active` más `cl_waiting`) servidos por un máximo de 20 a 25 conexiones reales (`sv_active` más `sv_idle`). Confírmalo desde PostgreSQL: ```bash sudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity WHERE datname = 'appdb';" ``` ```output count ------- 25 (1 row) ``` Al terminar, `pgbench` muestra el resultado: ```output number of clients: 100 number of threads: 4 ... tps = 18432.118305 (without initial connection time) ``` ## Cuándo no usar el modo transacción En modo transacción, dos transacciones consecutivas del mismo cliente pueden ir por conexiones distintas. Todo lo que dependa del estado de la sesión deja de funcionar de forma fiable: - `SET` fuera de una transacción (usa `SET LOCAL` dentro de ella). - `LISTEN`/`NOTIFY` y bloqueos consultivos a nivel de sesión (`pg_advisory_lock`). - Tablas temporales que deban sobrevivir entre transacciones. - `WITH HOLD` en cursores. Si tu aplicación usa estas funciones, crea una entrada aparte para ella con `pool_mode=session` en la sección `[databases]`: ```ini appdb_session = host=127.0.0.1 port=5432 dbname=appdb pool_mode=session ``` Las migraciones de esquema y los trabajos que usan bloqueos consultivos suelen conectarse directamente al puerto 5432. ## Solución de problemas - **`password authentication failed` solo a través de PgBouncer**: el hash de `userlist.txt` no coincide con el de `pg_authid` (por ejemplo, tras cambiar la contraseña). Vuelve a copiarlo y ejecuta `RELOAD`. - **`no such database: appdb`**: el nombre que usa el cliente no está en `[databases]`. - **`unsupported startup parameter`**: añade el parámetro indicado a `ignore_startup_parameters`. - **`prepared statement "..." does not exist`**: el driver usa sentencias preparadas con nombre; comprueba que `max_prepared_statements` es mayor que 0 o usa el modo sesión para esa aplicación. - **`cl_waiting` crece y sube la latencia**: el pool se queda corto. Aumenta `default_pool_size` sin superar el `max_connections` de PostgreSQL menos las conexiones que usen otros servicios. ## Conclusión Has instalado PgBouncer en Ubuntu 24.04 con pooling en modo transacción, autenticación SCRAM sin contraseñas en texto plano y una consola de administración para vigilar los pools. Como siguientes pasos, puedes reducir `max_connections` en PostgreSQL para liberar memoria, exportar las estadísticas de `SHOW STATS` a tu sistema de monitorización y activar TLS entre clientes y PgBouncer con `client_tls_sslmode` si las aplicaciones se conectan desde otras máquinas.