Connection Pooling #
Database connection pooling adalah salah satu konsep paling krusial dalam aplikasi backend modern, tetapi sering dianggap sepele. Banyak kasus bottleneck database, lonjakan latency, bahkan outage produksi bukan disebabkan query yang kompleks, melainkan manajemen koneksi database yang buruk.
Artikel ini akan membahas secara mendalam:
- Apa itu database connection pooling
- Cara kerjanya secara internal
- Implementasi di aplikasi non-distributed dan distributed
- Best practice berbeda untuk tiap skenario
- Kesalahan umum yang sering terjadi di production
Apa Itu Database Connection Pooling? #
Database connection pooling adalah mekanisme untuk:
- Membuat sejumlah koneksi database di awal (pool)
- Menyimpannya untuk digunakan ulang
- Menghindari overhead membuka dan menutup koneksi berulang kali
Alih-alih:
Request -> Open Connection -> Query -> Close Connection
Aplikasi akan melakukan:
Request -> Borrow Connection from Pool -> Query -> Return to Pool
Kenapa Open Connection Itu Mahal? #
Membuka koneksi database bukan operasi ringan:
- TCP handshake
- SSL/TLS negotiation
- Authentication ke database
- Alokasi resource di DB server
Jika dilakukan per request, dampaknya:
- Latency tinggi
- CPU DB melonjak
- Database kehabisan connection limit
Cara Kerja Database Connection Pooling #
Secara umum, pool memiliki komponen berikut:
Initial Pool Size Jumlah koneksi yang dibuat saat aplikasi start
Max Pool Size Batas maksimum koneksi yang boleh dibuat
Idle Connection Koneksi yang sedang tidak digunakan
Borrow & Return Mechanism
- Request meminjam koneksi
- Setelah selesai, koneksi dikembalikan
Timeout & Validation
- Timeout jika pool habis
- Health check koneksi sebelum dipakai
Ilustrasi Sederhana #
[App]
|
|--> Pool (10 connections)
|-- conn-1 (idle)
|-- conn-2 (in use)
|-- conn-3 (idle)
Jika semua koneksi dipakai:
- Request akan wait (blocking)
- Atau fail jika melewati timeout
Implementasi di Aplikasi Non-Distributed #
Karakteristik #
- 1 aplikasi / 1 instance
- Direct connect ke database
- Pool hanya hidup di dalam satu proses
Contoh Kasus #
- Monolith
- Admin panel
- Internal service
Pola Umum #
App Instance
└── Connection Pool (misalnya 20 koneksi)
└── Database
Kelebihan #
- Konfigurasi sederhana
- Mudah di-tuning
- Overhead rendah
Risiko Utama #
- Pool terlalu besar → DB overload
- Pool terlalu kecil → request antre
Best Practice (Non-Distributed) #
Sesuaikan pool size dengan workload
- CPU-bound app → pool kecil
- IO-bound app → pool sedang
Rule of thumb awal
max_pool ≈ (CPU core * 2) + effective concurrent querySelalu close / return connection
- Jangan simpan connection di global state
- Jangan pass connection antar goroutine / thread tanpa kontrol
Gunakan timeout
- Pool timeout
- Query timeout
Monitoring metrik pool
- Active connection
- Idle connection
- Wait time
Implementasi di Aplikasi Distributed #
Karakteristik #
- Banyak instance aplikasi
- Setiap instance punya pool sendiri
- Shared database
Contoh Kasus #
- Microservices
- Kubernetes / ECS
- Auto-scaling environment
Pola Umum #
[Service A] -> Pool (10)
[Service B] -> Pool (10)
[Service C] -> Pool (10)
Total DB connections = 30
⚠️ Inilah sumber masalah paling sering terjadi
Masalah Klasik di Distributed Pooling #
Connection Explosion #
Jika:
- 20 pod
- masing-masing pool max 20
Maka:
Total = 400 connections
Padahal DB hanya sanggup 200.
Auto Scaling Tanpa Pool Awareness #
- Pod scale up
- Pool ikut bertambah
- DB tiba-tiba overload
Long-Lived Idle Connection #
- Banyak pool idle
- DB resource tetap terpakai
- Memory & thread DB habis
Best Practice (Distributed Application) #
Hitung Pool Secara Global, Bukan Per Instance #
max_db_connection / total_instances = max_pool_per_instance
Contoh:
- DB max 300
- Max pod 30 → Pool per pod ≈ 10
Gunakan Connection Pooler di Depan DB #
Contoh:
- PgBouncer (Postgres)
- ProxySQL (MySQL)
Manfaat:
- Centralized pooling
- Aplikasi pakai pool kecil
- DB tidak dibanjiri koneksi
Kurangi Pool di Aplikasi #
Di distributed system:
- Pool kecil lebih aman
- 5–10 koneksi per instance sering cukup
Short-Lived Query, Bukan Long Transaction #
Jangan simpan connection terlalu lama
Hindari:
- Business logic panjang di dalam transaction
- Sleep / retry di dalam transaksi
Gunakan Read Replica dengan Pool Terpisah #
- Pool write kecil & ketat
- Pool read lebih longgar
Anti-Pattern yang Harus Dihindari #
- Pool size = max DB connection
- Tidak pakai timeout
- Connection leak (tidak dikembalikan)
- Long transaction di high traffic endpoint
- Scaling app tanpa scaling database
Ringkasan #
| Aspek | Non-Distributed | Distributed |
|---|---|---|
| Pool scope | Per aplikasi | Per instance |
| Risiko | Under/over pool | Connection explosion |
| Pool size | Lebih fleksibel | Harus kecil |
| Kompleksitas | Rendah | Tinggi |
| Best tool | Native pool | External pooler |
Penutup #
Database connection pooling bukan sekadar konfigurasi teknis, tetapi bagian dari arsitektur sistem. Kesalahan kecil dalam menentukan pool size bisa berdampak besar pada stabilitas database.