 Autor: [Robert Zasilny](/autorzy/robert-zasilny) Ekspert bezpieczeństwa i compliance · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  pgBouncer — connection pooling PostgreSQL

# pgBouncer — connection pooling dla PostgreSQL

Opublikowano: 10 kwietnia 2026 · Kategoria: Bazy danych / VPS

PostgreSQL jest wyjątkowo zasobożerny jeśli chodzi o połączenia — każde zajmuje osobny proces systemowy z kilkoma megabajtami RAM. Aplikacja webowa obsługująca 500 równoczesnych użytkowników może generować setki połączeń do bazy, co szybko przeciąża nawet mocny serwer. pgBouncer rozwiązuje ten problem utrzymując małą pulę rzeczywistych połączeń do PostgreSQL i multipleksując do nich wszystkich klientów aplikacji. Wynik: 10-krotnie więcej obsługiwanych klientów, mniejsze zużycie RAM, niższe latency pod obciążeniem.

## Instalacja pgBouncer

pgBouncer jest dostępny w standardowych repozytoriach Ubuntu/Debian. Działa jako proxy między aplikacją a PostgreSQL — aplikacja łączy się z pgBouncer (port 6432), a pgBouncer utrzymuje połączenia do Postgresa (port 5432).

\# Ubuntu / Debian
sudo apt update && sudo apt install pgbouncer -y

# Sprawdz wersje
pgbouncer --version

# Konfiguracja w:
# /etc/pgbouncer/pgbouncer.ini  — glowna konfiguracja
# /etc/pgbouncer/userlist.txt   — uzytkownik + haslo (MD5 lub SCRAM)

sudo systemctl enable pgbouncer
sudo systemctl start pgbouncer
sudo systemctl status pgbouncer

## Konfiguracja — pgbouncer.ini

Główny plik konfiguracyjny `/etc/pgbouncer/pgbouncer.ini` — kluczowe sekcje to `[databases]` (mapowanie baz) i `[pgbouncer]` (parametry puli):

\[databases\]
; Format: alias = host=... port=... dbname=...
; Aplikacja laczy sie jako "myapp" → pgBouncer proxy do lokalnego Postgresa
myapp = host=127.0.0.1 port=5432 dbname=myapp

; Mozna mapowac wiele baz
analytics = host=127.0.0.1 port=5432 dbname=analytics\_db

; Wildcard — wszystkie bazy przez pgBouncer
; \* = host=127.0.0.1 port=5432

\[pgbouncer\]
; Adres nasluchu (aplikacja laczy sie tutaj)
listen\_addr = 127.0.0.1
listen\_port = 6432

; Plik z uzytkownikami i haslem
auth\_file = /etc/pgbouncer/userlist.txt
auth\_type = md5

; TRYB PULI — kluczowy parametr
; session     = polaczenie Postgresa trzymane przez cala sesje klienta
; transaction = polaczenie zwracane po COMMIT/ROLLBACK (ZALECANY)
; statement   = zwracane po kazdym pojedynczym zapytaniu (zaawansowane)
pool\_mode = transaction

; Maks. polaczen od klientow (wszystkich razem)
max\_client\_conn = 1000

; Domyslny rozmiar puli per (baza, uzytkownik)
default\_pool\_size = 20

; Zapas polaczen przy skoku ruchu
reserve\_pool\_size = 5
reserve\_pool\_timeout = 3

; Czas oczekiwania klienta na wolne polaczenie (sekundy)
; Po tym czasie klient dostaje blad
client\_login\_timeout = 60

; Logi
log\_connections = 0
log\_disconnections = 0
log\_pooler\_errors = 1

; Dostep do bazy statystyk pgbouncer (do monitorowania)
stats\_users = stats, pgbouncer

## Konfiguracja userlist.txt i pg\_hba.conf

pgBouncer uwierzytelnia klientów samodzielnie (na podstawie `userlist.txt`), a następnie łączy się z PostgreSQL jako zdefiniowany użytkownik. Hasła w userlist.txt muszą być zahashowane MD5 w formacie `md5 + MD5(haslo + uzytkownik)`:

\# Generuj hash MD5 dla uzytkownika "appuser" z haslem "tajnehaslo"
echo -n "tajnehasloappuser" | md5sum
# Wynik: abc123... (32 znaki)

# /etc/pgbouncer/userlist.txt — format: "uzytkownik" "md5HASH"
"appuser" "md5abc123def456..."
"stats"   "md5xyz789..."

# Alternatywnie: skopiuj hash z PostgreSQL
psql -U postgres -c "SELECT usename, passwd FROM pg\_shadow WHERE usename='appuser';"

\# /etc/postgresql/15/main/pg\_hba.conf
# Zezwol na polaczenia od pgBouncer (127.0.0.1 lub dedykowany IP)
# TYPE  DATABASE  USER      ADDRESS       METHOD
host    myapp     appuser   127.0.0.1/32  md5
host    all       stats     127.0.0.1/32  md5

# Reload PostgreSQL po zmianach
sudo systemctl reload postgresql

# Restart pgBouncer po zmianach konfiguracji
sudo systemctl restart pgbouncer

## Tryby pool\_mode — szczegółowe porównanie

pool\_mode

Kiedy zwraca połączenie

Gęstość multipleksowania

Ograniczenia

Użycie

**session**

Koniec sesji klienta

Niska (1:1)

Brak (pełna kompatybilność)

Migracja bez zmian w aplikacji

**transaction**

COMMIT / ROLLBACK

Wysoka (50:1)

Brak SET, LISTEN, temp tables

Typowe aplikacje webowe

**statement**

Koniec każdego zapytania

Bardzo wysoka

Brak transakcji multi-statement

Read-only analytics, cache warmup

**Uwaga dla transaction mode:** Jeśli Twoja aplikacja używa `SET search_path`, `SET LOCAL`, `LISTEN/NOTIFY`, prepared statements z `PREPARE` lub tymczasowych tabel — potrzebujesz obejść to przez `server_reset_query` lub przełączyć na session mode.

## Połączenie z aplikacji przez pgBouncer

Aplikacja łączy się z pgBouncer dokładnie tak samo jak z PostgreSQL — zmieniasz tylko port z 5432 na 6432:

\# PHP (PDO) — tylko zmiana portu z 5432 na 6432
$pdo = new PDO('pgsql:host=127.0.0.1;port=6432;dbname=myapp', 'appuser', 'tajnehaslo');

# Python (psycopg2)
conn = psycopg2.connect(
    host='127.0.0.1',
    port=6432,
    dbname='myapp',
    user='appuser',
    password='tajnehaslo'
)

# Node.js (pg)
const pool = new Pool({
  host: '127.0.0.1',
  port: 6432,
  database: 'myapp',
  user: 'appuser',
  password: 'tajnehaslo',
  max: 10  // Pool w aplikacji — dodatkowa warstwa
});

# Django settings.py
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'HOST': '127.0.0.1',
    'PORT': '6432',
    'NAME': 'myapp',
    'USER': 'appuser',
    'PASSWORD': 'tajnehaslo',
  }
}

## Monitoring — SHOW POOLS i SHOW STATS

pgBouncer udostępnia wirtualną bazę `pgbouncer` na tym samym porcie do monitorowania stanu puli. Połącz się jako użytkownik `stats`:

\# Polacz sie do konsoli statystyk
psql -h 127.0.0.1 -p 6432 -U stats pgbouncer

-- Stan pul polaczen
SHOW POOLS;
-- database | user    | cl\_active | cl\_waiting | sv\_active | sv\_idle | maxwait
-- myapp    | appuser | 45        | 0          | 18        | 2       | 0

-- Statystyki ruchu
SHOW STATS;
-- database | total\_xact\_count | total\_query\_count | avg\_xact\_duration\_us

-- Aktywni klienci
SHOW CLIENTS;

-- Polaczenia do PostgreSQL
SHOW SERVERS;

-- Konfiguracja live
SHOW CONFIG;

-- Przeladuj konfiguracje bez restartu
RELOAD;

-- Zatrzymaj przyjmowanie nowych polaczen (graceful)
PAUSE myapp;
RESUME myapp;

Metryka

Znaczenie

Alert gdy

`cl_active`

Klienci aktywnie wykonujący zapytanie

Zbliża się do max\_client\_conn

`cl_waiting`

Klienci czekający na wolne połączenie

Wartość > 0 przez więcej niż kilka sekund

`sv_active`

Połączenia do Postgresa z aktywnym zapytaniem

Równa pool\_size = brak rezerwy

`sv_idle`

Wolne połączenia w puli

Stale 0 = pool za mały

`maxwait`

Najdłuższy czas oczekiwania klienta (s)

Wartość > 1s = problem z rozmiarem puli

## Dobieranie rozmiaru puli — reguły kciuka

-   **default\_pool\_size** — zacznij od liczby rdzeni CPU serwera PostgreSQL (np. 4-rdzeniowy = pool 4-8). Zwiększaj stopniowo obserwując `cl_waiting`.
-   **max\_client\_conn** — ile klientów (aplikacji) może jednocześnie trzymać połączenie z pgBouncer. Może być 10-100× większe niż `default_pool_size`.
-   **PostgreSQL max\_connections** — musi być > suma pool\_size wszystkich baz + połączenia administracyjne. Formuła: `max_connections = sum(pool_sizes) + 10`.
-   **server\_idle\_timeout** — jak długo pgBouncer trzyma nieużywane połączenie do Postgresa (domyślnie 600s). Zmniejsz do 60-120s jeśli baza ma restrykcyjny limit.
-   **Wiele pul** — każda para (baza, użytkownik) ma osobną pulę. Jeśli masz wiele użytkowników bazy, sumuj ich pool\_size przy planowaniu max\_connections.

## Najczęstsze pytania

Do czego służy pgBouncer i kiedy go potrzebuję? +

pgBouncer to lekki connection pooler dla PostgreSQL. PostgreSQL tworzy osobny proces systemowy na każde połączenie klienta (nawet 5 MB RAM per connection). Przy 1000 równoczesnych klientów (typowe dla aplikacji webowych) oznacza to 5 GB RAM tylko na procesy połączeń. pgBouncer utrzymuje mały basen rzeczywistych połączeń do Postgresa (np. 20) i multipleksuje do nich liczne równoczesne sesje klientów. Wymagany gdy: masz dużo krótko-żyjących połączeń (PHP-FPM, serverless), widzisz błędy "too many connections", latency rośnie pod obciążeniem.

Jaka jest różnica między pool\_mode transaction, session i statement? +

Session mode: połączenie z Postgresem jest przypisane klientowi na czas całej sesji (bezpieczny, ale słabo multipleksuje — jak bez poolera). Transaction mode: połączenie jest zwracane do puli po COMMIT/ROLLBACK — pozwala 1000 klientom współdzielić 20 połączeń. Najczęściej używany. Ograniczenie: SET/LISTEN/NOTIFY, temporary tables, advisory locks nie działają między transakcjami. Statement mode: zwraca po każdym pojedynczym zapytaniu — maksymalna gęstość puli, ale nie obsługuje multi-statement transakcji. Tylko dla prostych read-only workloadów.

Czy pgBouncer zastępuje połączenie pool w aplikacji (np. connection pool w Node.js)? +

Nie zastępuje, ale uzupełnia. Pool w aplikacji (np. pg w Node.js, SQLAlchemy w Pythonie) utrzymuje połączenia w ramach jednego procesu i redukuje koszt nawiązywania połączeń z aplikacji. pgBouncer działa na poziomie sieci i konsoliduje połączenia z WIELU instancji aplikacji (np. 10 podów Node.js × 10 połączeń = 100 → pgBouncer mapuje je na 20 rzeczywistych). Kombinacja obu daje najlepszy wynik: pool w aplikacji dla lokalnej wydajności + pgBouncer dla globalnej konsolidacji.

Jak monitorować pgBouncer i skąd wiedzieć że działa poprawnie? +

Połącz się do bazy pgbouncer (port 6432, użytkownik stats): psql -p 6432 -U stats pgbouncer. Komendy: SHOW POOLS (cl\_active, cl\_waiting, sv\_active, sv\_idle, sv\_tested), SHOW STATS (total\_requests, total\_received, avg\_query\_duration), SHOW CLIENTS, SHOW SERVERS. Kluczowe metryki: cl\_waiting > 0 znaczy klienci czekają na wolne połączenie (zwiększ pool\_size lub dodaj serwery), avg\_query\_duration rośnie = wolne zapytania lub przeciążony Postgres.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z dużą ilością RAM dla baz PostgreSQL i pgBouncer — od 4 GB RAM

VPS + RAM

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikr.us

Budżetowy VPS do nauki konfiguracji PostgreSQL i connection pooling

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

LH.pl

Hosting zarządzany z PostgreSQL w chmurze — bez potrzeby konfiguracji pgBouncer

Managed DB

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

## Powiązane strony

-   [MySQL replication master-slave](/baza-wiedzy/mysql-replication-master-slave)
-   [MySQL slow query log — optymalizacja](/baza-wiedzy/mysql-slow-query-log)
-   [Redis Sentinel — High Availability](/baza-wiedzy/redis-sentinel-ha)
-   [Wszystkie artykuły](/baza-wiedzy/)