# PgBouncer'da Session/Transaction/Statement modlarından hangisini seçmeliyim?

> Web filosunda Transaction modunu seçin; bedeli protokol seviyesi prepared statement'lardır, onları kapatın ya da PgBouncer 1.21+ desteğini açın.

- Soruldu: 2026-05-20
- Yanıtlandı: 2026-05-23
- Soran: Pelin
- Etiketler: performans, postgresql, veritabani
- Kaynak: https://www.muhammetsafak.com.tr/sor-bakalim/pgbouncer-session-transaction-statement-modu-ve-prepared-statement/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Mikroservislerimiz (toplam ~50 pod) PostgreSQL'e doğrudan bağlanıyor ve her pod en az 10 bağlantı açıyor. Yoğun yükte `max_connections` limitine (örneğin 500) dayanıp hata alıyoruz; limiti artırmak RAM'i dikeyde katlıyor.

Araya PgBouncer koymayı planlıyoruz. Session, Transaction, Statement modlarından hangisini seçmeliyiz? Uygulamadaki prepared statement'lar bu seçimden nasıl etkilenir?


Kısa cevap: Web/mikroservis filosu için **Transaction modu** — çok-statement'lı trafikte bağlantı yeniden kullanımını en yükseğe çıkaran en pratik seçenek bu.

Yaşadığın şey net: 50 pod × min bağlantı, `max_connections`'ı tüketiyor. PgBouncer tam da bunu çözer — çok sayıda client bağlantısını az sayıda sunucu bağlantısına multiplexler, yani `max_connections`'ı şişirmeden RAM'i kurtarırsın.

1. **Transaction modu en yüksek yeniden kullanımı verir.** Sunucu bağlantısını her **transaction sonunda** havuza iade eder; iki ardışık transaction farklı sunucu bağlantısına düşebilir. Yüzlerce kısa-ömürlü mikroservis isteği için doğru mod budur, çünkü bağlantı boşta beklemez.
2. **Session modu avantajı çöpe atar.** Her client'a tüm oturumu boyunca bir sunucu bağlantısı bağlar — yani gerçekte 50 pod yine 50+ sunucu bağlantısı tutar; multiplexing kazancı kaybolur. Sadece session state'e gerçekten muhtaçsan mantıklı.
3. **Statement modu fazla kısıtlayıcı.** Bağlantıyı her statement sonunda iade eder, bu da **çok statement'lı transaction'ları** bozar. Pratikte web uygulaması için kullanılmaz; sadece tek-statement, autocommit dünyalarda iş görür.
4. **Asıl tuzak: Transaction modu prepared statement ve session state'i bozar.** Protokol seviyesi prepared statement'lar, `SET`, advisory lock ve `LISTEN` gibi bağlantıya bağlı durumlar farklı sunucu bağlantısına düşünce kaybolur. Çözüm: client-side prepared statement'ları kapat (örn. PDO `ATTR_EMULATE_PREPARES`) **ya da** PgBouncer 1.21+ prepared-statement desteğini aç; ve hiçbir zaman statement'lar arası session state'e güvenme.
5. **`default_pool_size`'ı makul tut.** Sunucu bağlantısı havuzunu kocaman yapma — multiplexing'in tüm anlamı az sunucu bağlantısıyla çok client'a hizmet etmek. Önce gerçek eşzamanlılığını ölç, havuzu ona göre boyutla.

**Sonuç:** Ben olsam **Transaction modu** seçerdim, uygulamada server-side/protokol prepared statement'ları kapatırdım (ya da PgBouncer'ı 1.21+'a yükseltirdim) ve `default_pool_size`'ı ölçülmüş eşzamanlılığa göre dar tutardım. Session modu sorununu çözmez, Statement modu uygulamanı kırar. Bu arada, dikeyde `max_connections` ve RAM'i katlamak yerine bağlantı havuzlamayı çözmek çoğu zaman tam da PostgreSQL'i "yeterli" kılan hamledir — bu tartışmanın derinine sade.dev'deki yazıda girdim.

## İlgili Yazılar

- [PostgreSQL Her Şeye Yeter mi?](https://sade.dev/tr/journal/postgresql-her-seye-yeter-mi) — sade.dev
- [Sadece 'pending' satırları taranan bir kuyruk tablosunda partial index kullanmalı mıyım?](https://www.muhammetsafak.com.tr/sor-bakalim/sadece-pending-satirlari-taranan-bir-kuyruk-tablosunda-partial-index-kullanmali-miyim/) — Sor Bakalım
- [PostgreSQL'de composite index kolon sırasını nasıl seçerim?](https://www.muhammetsafak.com.tr/sor-bakalim/postgresql-composite-index-kolon-sirasi-nasil-secilir/) — Sor Bakalım
- [Sürekli güncellenen bir sessions tablosunda staging'de Index Scan alan sorgu production'da neden Seq Scan'e düşüyor, EXPLAIN ile nasıl teşhis ederim?](https://www.muhammetsafak.com.tr/sor-bakalim/surekli-guncellenen-bir-sessions-tablosunda-stagingde-index-scan-alan-sorgu-productionda/) — Sor Bakalım
