PgBouncer 9

PgBouncer vs pgcat vs Supavisor, 2026년에 뭘 쓸까

Postgres 커넥션 풀러 얘기다. 15년 넘게 PgBouncer가 사실상 표준이었다. 근데 최근 몇 년 사이에 pgcat(Rust), Supavisor(Elixir) 같은 대안이 부쩍 눈에 띈다. 우리 팀에서도 지난 분기에 새 서비스용 풀러를 뭘로 갈지 논의가 있었고, 실제로 각각을 조금씩 다르게 굴려봤다. 이 글은 그 경험을 바탕으로 세 개를 나열해보는 글이다. "이거 써라"는 아니고, 어떤 상황에서 뭐가 맞더라 정도의 정리.세 개가 각자 어떤 물건인가PgBouncer는 여전히 단일 바이너리에 2MB짜리 프로세스로 커넥션 수천 개를 받아낸다. 트랜잭션 모드 풀링, 심플한 config, 문서화 잘 되어 있고, 튜닝 노하우가 인터넷에 널려있다. 단점은 단일 스레드라는 것. CPU 하나를 다 태우면 그게..

IT/DB 운영 2026.08.06

PgBouncer transaction pool로 갈아탄 다음 날 새벽에 벌어진 일

session pooling에서 transaction pooling으로 갈아탄 지 이틀째 되던 날 새벽 2시 반, 폰이 울렸다. 결제 API의 P99가 800ms를 넘겼다는 알람. 침대에서 노트북을 여는 순간 이미 뭐가 원인인지 짐작이 갔다. prepared statement 다.왜 갈아탔나우리 팀에서 PgBouncer는 오래전부터 session pool로 돌고 있었다. 백엔드가 Django였고, connection이 세션 내내 유지되는 게 편했다. 그런데 최근 서비스가 커지면서 DB 커넥션 수가 감당이 안 됐다. RDS 앞단 PgBouncer에 client는 3천이 넘게 붙는데 server 커넥션은 200~300 정도로 억제하고 싶었다. session pooling에서는 client 한 명이 붙어있는 ..

IT/DB 운영 2026.07.31

idle_in_transaction_session_timeout, 이거 하나로 커넥션 풀이 살아난다

오늘 알게 된 건 아니고 예전부터 알고는 있었는데, 최근에 신규 서비스 튜닝 도우면서 "아 이거 진짜 모르는 팀 아직도 많구나" 싶어서 짧게 남긴다.PostgreSQL 파라미터 중에 idle_in_transaction_session_timeout 라는 게 있다. 이름 그대로 트랜잭션 시작해놓고 아무것도 안 하는 세션을 강제 종료해주는 값이다. 기본값은 0, 즉 비활성이다.왜 이게 문제가 되나전형적인 시나리오는 이렇다.앱에서 BEGIN 날려서 트랜잭션 열어놓고, 그 사이에 외부 API 호출한다. 근데 그 API가 30초쯤 걸린다. 그동안 이 커넥션은 어떤 상태냐면 idle in transaction. 살아는 있는데 아무 일도 안 하고, 그런데 락은 잡고 있을 수도 있다.이런 커넥션이 몇 개 쌓이면 pg_s..

IT/DB 운영 2026.07.16

session pooling에서 transaction pooling으로 갈아탄 후 3주간 벌어진 일

지난달에 결국 pgbouncer 풀 모드를 session에서 transaction으로 바꿨다. 결과부터 말하면 잘 됐다. 근데 그 3주 동안 두 번은 새벽에 잠에서 깼고, 한 번은 회의 도중에 대시보드 보고 얼굴이 하얘졌다. 기록 삼아 남긴다.왜 갈아탔나우리 서비스는 백엔드 20개 파드가 각각 커넥션 풀 20을 잡는다. 그러니까 idle 상태에서도 Postgres 쪽에는 400개 커넥션이 잡혀 있다는 얘기다. Aurora r6g.2xlarge 기준 max_connections가 900 남짓인데, 스케일 아웃 몇 번 하면 아슬아슬해진다.그동안 pgbouncer를 session pooling으로 쓰고 있었는데, 이건 사실상 아무 이득이 없었다. 클라이언트 커넥션 하나가 백엔드 커넥션 하나를 트랜잭션 단위가 ..

IT/DB 운영 2026.07.05

PgBouncer transaction vs session 모드, 뭘 쓸까

Postgres 앞에 PgBouncer를 두는 건 거의 관습처럼 되어 있다. 그런데 막상 처음 도입할 때 보면 pool_mode 선택지가 세 개 있고, 그중 실제로 쓰는 건 거의 둘 — transaction과 session이다. 둘 다 써본 입장에서 정리해본다. 어느 쪽이 정답이라기보다, 트레이드오프가 꽤 명확하다.참고로 PgBouncer 1.21 이후 transaction 모드에서도 prepared statements가 지원되기 시작했다. 이게 의외로 선택 기준을 흔든다. 예전에는 ORM/드라이버 호환성 때문에 어쩔 수 없이 session 모드를 골랐던 케이스들이 다시 transaction으로 돌아갈 만한 여지가 생겼다.session 모드 — 가장 안전하지만 풀링 효과가 약하다pool_mode = se..

IT/DB 운영 2026.06.29

pgbouncer transaction mode에서 prepared statement 깨진 새벽 사건

지난주 새벽에 또 깼다. 4시쯤 핸드폰이 미친 듯이 울리는데, 화면을 보니 prepared statement "S_42" does not exist 에러가 분당 수천 건씩 쌓이고 있었다. 결제 API 쪽이었는데, 그날따라 더 짜증났던 건 — 두 시간 전에 내가 직접 머지한 PR 때문이라는 게 거의 확실했기 때문이다.결론부터 말하면 pgbouncer transaction pooling 모드 + 새 JDBC 드라이버 조합이 문제였다. 근데 거기까지 가는 과정이 정말 길었다.새벽 4시, 일단 롤백부터운영 룰은 단순하다. 새벽에 깨면 일단 의심되는 배포부터 롤백. 두 시간 전 머지한 PR이 두 개 있었다 — 하나는 pgbouncer 버전 업(1.18 → 1.23), 다른 하나는 백엔드 서비스의 PostgreSQ..

IT/DB 운영 2026.06.17

PgBouncer transaction mode에 prepared statement 켰다가 새벽에 깬 이야기

지난주 일요일 새벽 2시쯤 알림이 왔다. 결제 API 쪽에서 prepared statement "S_3" does not exist 에러가 분당 수백 건씩 찍히고 있었다. 그 전날 PgBouncer를 1.25.1로 올린 게 화근이었다. 안 그래도 PG16.11에 PgBouncer 1.25.1 조합에서 prepared statement 관련 버그 리포트가 올라온 게 있었는데, 우리도 그 케이스에 정확히 걸려든 거였다.이번 글은 그날 새벽 내가 뭘 보고 뭘 했고, 최종적으로 어떻게 마무리됐는지에 대한 기록이다. 깔끔한 해결책 같은 건 아직 없다. 워크어라운드로 일단 막아둔 상태.배경: 왜 transaction mode + prepared statement를 켰나작년에 우리 팀은 PgBouncer를 1.21로..

IT/DB 운영 2026.05.25

PgBouncer transaction pooling, prepared statement 함정에서 빠져나온 이야기

지난주 화요일 오후, 모니터링 알람이 울렸다. PgBouncer 앞단의 connection 사용량이 평소 대비 3배 가까이 튀어 있었고, 어플리케이션 쪽 P99 레이턴시는 슬슬 200ms를 넘기고 있었다. 트래픽은 평소 수준. 이상한 점은 RDS Postgres의 active connection 수가 거의 변동이 없다는 거였다. 즉, 클라이언트 → PgBouncer 사이에서 뭔가 막혀 있다는 뜻이다.이번 글은 그날 밤 새벽 2시까지 잡고 있던 이 문제를 어떻게 추적했는지, 그리고 결국 prepared statement와 transaction pooling이 충돌하던 지점을 어떻게 풀어냈는지에 대한 기록이다. 결론부터 말하면, 우리가 두 달 전에 한 PgBouncer 버전 업그레이드가 진짜 원인이었다.처음..

IT/DB 운영 2026.05.14

PgBouncer transaction 모드에서 prepared statement 제대로 쓰는 법

왜 굳이 켜야 하나PgBouncer 1.21에서 transaction pooling 모드에서도 prepared statement를 쓸 수 있게 된 게 벌써 2년 가까이 됐다. 우리 팀도 작년 가을에 1.22로 올리고 max_prepared_statements를 켰는데, 그동안 마주친 함정 몇 개가 있어서 정리해둔다. 비슷한 마이그레이션을 앞두고 있는 분들에게 도움이 됐으면 한다.이 글은 "PgBouncer는 뭔가요"부터 시작하지 않는다. 이미 transaction 모드로 PgBouncer를 운영 중이고, 애플리케이션이 prepared statement를 쓰고 있거나 쓰고 싶은 상황을 가정한다.JDBC, asyncpg, pgx, psycopg3 같은 모던 드라이버는 기본적으로 Parse/Bind/Execu..

IT/DB 운영 2026.04.29