풀 포화와 대기열 진단
사용자가 알아차리기 전에 PgBouncer 통계를 읽어 소진된 풀과 대기 중인 클라이언트를 발견하는 방법을 배웁니다.
풀 포화와 대기열 진단은(는) CoddyKit의 무료 PostgreSQL Performance & Query Optimization 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 PostgreSQL Performance & Query Optimization 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. PostgreSQL Performance & Query Optimization 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Why Pools Saturate
PgBouncer multiplexes many client connections onto a small set of server connections. In transaction pooling, a server connection is borrowed only for the duration of a transaction, then returned to the pool.
A pool saturates when every server connection is busy and new client requests must wait in a queue. The queue is invisible from the database's side — Postgres just sees a steady, capped number of backends — so you must read PgBouncer's own stats to see the pressure building.
pool_size= max server connections per (database, user) pool- Waiting clients = demand that exceeds that ceiling
Connecting to the Admin Console
PgBouncer exposes a virtual database called pgbouncer. Connect to it with psql using a user listed in admin_users, then run SHOW commands to read its internal state.
This is your primary diagnostic surface — there is no separate dashboard required.
-- Connect to the PgBouncer admin console
psql -h 127.0.0.1 -p 6432 -U pgbouncer pgbouncer
-- Once inside, list the available diagnostic views
SHOW HELP;SHOW POOLS: the cl_waiting Column
SHOW POOLS is the single most important command for spotting saturation. Each row is one pool, identified by database and user.
cl_active— clients currently bound to a server connectioncl_waiting— clients queued, waiting for a free server connectionsv_active— server connections busy serving a transactionsv_idle— server connections free to be assigned
The rule of thumb: any sustained cl_waiting > 0 with sv_idle = 0 means the pool is saturated.
-- Run inside the pgbouncer admin database
SHOW POOLS;Reading a Saturated Pool
Compare two snapshots. A healthy pool keeps spare idle servers and an empty wait queue:
cl_active=18 cl_waiting=0 sv_active=6 sv_idle=14→ plenty of headroomcl_active=20 cl_waiting=47 sv_active=20 sv_idle=0→ saturated and queueing
In the second case sv_active equals pool_size, sv_idle is zero, and 47 clients are stuck in line. Latency users feel = queue wait + actual query time.
maxwait: How Long the Queue Has Been Stuck
SHOW POOLS also reports maxwait and maxwait_us — the time the oldest waiting client has been queued, in seconds and microseconds.
This is your early-warning metric. A non-zero and growing maxwait means clients are not just queued but starving. If maxwait approaches your application's statement or connection timeout, requests will start failing before users even get a response.
maxwait = 0→ nobody is waiting right nowmaxwait = 4and climbing → act now, the pool is too small or the DB is too slow
-- Focus on the queue-pressure columns
-- (column subset shown conceptually; SHOW POOLS returns all)
SHOW POOLS;
-- Watch: database | user | cl_waiting | sv_idle | maxwait | maxwait_usPolling for Saturation Trends
A single snapshot can mislead — pools fill and drain in bursts. Watch the trend by polling the admin console on an interval and logging the key columns.
From a shell you can loop psql and grep the pool you care about. Rising cl_waiting across samples confirms real saturation rather than a momentary spike.
-- Poll PgBouncer every 2 seconds, watch one pool
watch -n 2 "psql -h 127.0.0.1 -p 6432 -U pgbouncer \
-d pgbouncer -c 'SHOW POOLS;' | grep ' app_db '"SHOW STATS: Throughput and Query Time
Saturation has two root causes: too little capacity, or queries that hold server connections too long. SHOW STATS separates them.
avg_query_time— average query duration in microsecondsavg_xact_time— average transaction duration; long transactions hog server connectionsavg_query_count— queries per second
If avg_xact_time is high, raising pool_size only delays the problem — fix the slow transactions instead.
-- Per-database throughput and timing averages
SHOW STATS;Correlating With Postgres Itself
PgBouncer tells you clients are waiting; Postgres tells you why the server connections are busy. Query pg_stat_activity on the real database to see what those backends are doing.
Long-running queries, idle-in-transaction sessions, or lock waits will pin the limited server connections and feed the PgBouncer queue.
-- On the actual Postgres server: find what is holding backends
SELECT pid,
state,
wait_event_type,
wait_event,
now() - xact_start AS xact_age,
left(query, 60) AS query
FROM pg_stat_activity
WHERE datname = 'app_db'
AND state <> 'idle'
ORDER BY xact_age DESC NULLS LAST;The idle in transaction Trap
A frequent cause of PgBouncer queueing is sessions left idle in transaction: the app opened a transaction, then stalled (waiting on an external call, a slow loop, or a bug) without committing. That server connection stays checked out and unavailable to the pool.
Hunt these down explicitly — they often explain a saturated pool whose avg_query_time looks low.
-- Sessions holding a connection open but doing no work
SELECT pid,
usename,
now() - state_change AS idle_for,
left(query, 80) AS last_query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY idle_for DESC;SHOW CLIENTS and SHOW SERVERS
For finer detail, two more admin views drill into individual connections:
SHOW CLIENTS— every client link; astateofwaitingplus a largewaitvalue pinpoints the starving clientsSHOW SERVERS— every server link and which client (if any) currently owns it
Use these when SHOW POOLS shows queueing and you need to identify exactly which clients or application hosts are affected.
-- Per-connection detail; look for state='waiting' and high 'wait'
SHOW CLIENTS;
-- Which server links are linked to which clients
SHOW SERVERS;Turning Diagnosis Into Action
Once the stats point to a cause, the fix follows directly:
- High
cl_waiting, lowavg_xact_time→ genuine capacity shortage; raisepool_size(and check Postgresmax_connectionshas room) - High
avg_xact_timeor manyidle in transaction→ fix the app/queries; more pool size won't help maxwaitnear app timeout → tunequery_wait_timeoutso clients fail fast instead of hanging- One pool starved, others idle → consider a dedicated pool or
reserve_pool_size
-- Example pgbouncer.ini tuning after diagnosis
[databases]
app_db = host=10.0.0.5 port=5432 dbname=app_db pool_size=40
[pgbouncer]
pool_mode = transaction
default_pool_size = 20
reserve_pool_size = 5
reserve_pool_timeout = 3
query_wait_timeout = 10Quick Check
You read SHOW POOLS and see this row for one pool.
Recap
You can now diagnose PgBouncer pool saturation before users feel it:
- SHOW POOLS — watch
cl_waiting,sv_idle, andmaxwait; sustained waiting with zero idle servers means saturation - SHOW STATS — use
avg_xact_timeto tell a capacity shortage from slow transactions - pg_stat_activity — find the long-running and
idle in transactionbackends pinning your pool - SHOW CLIENTS / SHOW SERVERS — drill down to the exact affected connections
Act on the cause: add capacity only when queries are fast; otherwise fix the transactions, and tune query_wait_timeout so clients fail fast instead of hanging.
자주 묻는 질문
“풀 포화와 대기열 진단” 강의는 무료인가요?
네 — “풀 포화와 대기열 진단” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 PostgreSQL Performance & Query Optimization 강의 전체를 잠금 해제할 수 있습니다. PostgreSQL Performance & Query Optimization 강의에는 총 4개의 강의가 포함되어 있습니다.
“풀 포화와 대기열 진단”에서 뭘 배우나요?
사용자가 알아차리기 전에 PgBouncer 통계를 읽어 소진된 풀과 대기 중인 클라이언트를 발견하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 PostgreSQL Performance & Query Optimization을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
PostgreSQL Performance & Query Optimization을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 PostgreSQL Performance & Query Optimization은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“풀 포화와 대기열 진단” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 PostgreSQL Performance & Query Optimization 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 PostgreSQL Performance & Query Optimization 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.