Database Connection Pool: Konsep, Masalah Umum, dan Best Practice (Contoh Golang + GORM)
Dalam aplikasi backend modern, database connection pool adalah salah satu komponen paling krusial—namun sering diremehkan. Banyak masalah performa, latency tinggi, bahkan outage di production bukan karena query lambat, tapi karena connection pool yang salah konfigurasi.
Artikel ini akan membahas:
- Apa itu connection pool (secara realistis, bukan textbook)
- Masalah umum jika tidak disetel dengan benar
- Cara kerja connection pool di Go
- Contoh implementasi Golang + GORM
- Best practice:
max open connection,max idle connection,max idle timeout, dll - Rekomendasi angka + cara berpikirnya
Apa Itu Database Connection Pool?
Secara sederhana:
Connection pool adalah sekumpulan koneksi database yang dipertahankan dan digunakan ulang oleh aplikasi.
Tanpa pool:
- Setiap request → buka koneksi baru
- Query selesai → koneksi ditutup
- Overhead besar (TCP, TLS, auth, dsb)
Dengan pool:
- Koneksi dibuat di awal
- Disimpan di pool
- Dipakai ulang oleh banyak request
Kenyataan di Production
- Koneksi database itu mahal
- Database punya limit koneksi
- Terlalu banyak koneksi = database overload
- Terlalu sedikit koneksi = request antre (latency naik)
Connection pool adalah alat untuk mengontrol tekanan ke database.
Masalah Umum Tanpa / Salah Konfigurasi Connection Pool
Default Setting (Paling Berbahaya)
Banyak engineer berpikir:
“Kan sudah pakai GORM / database/sql, pasti aman.”
Faktanya:
- Default
MaxOpenConns = 0→ unlimited - Default
MaxIdleConns = 2 - Default timeout → tidak jelas
Akibatnya:
- Traffic spike → ribuan koneksi
- Database kehabisan resource
- Aplikasi terlihat “random timeout”
Max Connection Terlalu Besar
Contoh:
- DB limit: 100 connections
- Aplikasi punya 5 pod
- Set
MaxOpenConns = 50
Total:
5 × 50 = 250 connections
Database langsung sekarat.
Max Connection Terlalu Kecil
Kebalikannya:
- Banyak goroutine
- Semua menunggu koneksi
- CPU idle tapi latency tinggi
Ini sering terjadi di Go karena goroutine murah, tapi DB connection tidak murah.
Cara Kerja Connection Pool di Go
Di Go:
- Connection pool dikelola oleh
database/sql - GORM hanya membungkusnya
- Semua setting pool dilakukan di
sql.DB
Alurnya:
GORM → database/sql → actual DB connection
Artinya:
Kalau kamu pakai GORM, tetap wajib mengatur connection pool secara eksplisit.
Contoh Implementasi Golang + GORM
Setup Database
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
Ambil *sql.DB dari GORM:
sqlDB, err := db.DB()
if err != nil {
log.Fatal(err)
}
Konfigurasi Connection Pool (WAJIB)
Max Open Connections
sqlDB.SetMaxOpenConns(20)
Artinya:
- Maksimal 20 koneksi aktif ke database
- Jika habis → request akan menunggu
Best Practice:
Jangan pakai angka besar tanpa alasan
Hitung berdasarkan:
- DB max connections
- Jumlah instance aplikasi
Max Idle Connections
sqlDB.SetMaxIdleConns(10)
Artinya:
- Koneksi yang menganggur tapi tetap disimpan
- Menghindari overhead buka koneksi baru
Best Practice:
- Biasanya 50–75% dari MaxOpenConns
- Jangan lebih besar dari MaxOpenConns
Connection Max Lifetime
sqlDB.SetConnMaxLifetime(30 * time.Minute)
Artinya:
Koneksi akan dipaksa ditutup setelah waktu tertentu
Mencegah:
- Koneksi “tua”
- Masalah network
- Load balancer timeout
Best Practice:
- 15–60 menit
- Lebih kecil dari idle timeout di database / proxy
Connection Max Idle Time (Go ≥ 1.15)
sqlDB.SetConnMaxIdleTime(10 * time.Minute)
Artinya:
- Jika koneksi idle terlalu lama → ditutup
- Menghemat resource
Best Practice:
- 5–15 menit
- Cocok untuk traffic tidak stabil
Contoh Konfigurasi Ideal (Umum)
Untuk 1 service instance:
sqlDB.SetMaxOpenConns(20)
sqlDB.SetMaxIdleConns(10)
sqlDB.SetConnMaxLifetime(30 * time.Minute)
sqlDB.SetConnMaxIdleTime(10 * time.Minute)
Cara Menentukan Angka yang Benar
Lihat DB Limit
Misal:
Postgres max_connections = 100
Hitung Jumlah Instance
Misal:
5 pods
Bagi Secara Aman
100 / 5 = 20
➡️ MaxOpenConns = 20
Sisakan buffer untuk:
- Migration
- Admin
- Background job
Sesuaikan dengan Traffic
- Query cepat → bisa lebih kecil
- Query berat / lama → jangan kebanyakan
Anti-Pattern yang Harus Dihindari
- Tidak set connection pool sama sekali ❌
- Set
MaxOpenConnsterlalu besar “biar aman” ❌ - Menganggap database bisa autoscale seperti aplikasi ❌
- Menggunakan satu database untuk terlalu banyak service tanpa perhitungan ❌
Observability: Jangan Blind
Wajib monitor:
- Active connections
- Idle connections
- Wait time (connection wait)
Jika:
- CPU rendah
- Latency tinggi
- Banyak goroutine blocked
➡️ besar kemungkinan bottleneck di connection pool
Kesimpulan
Database connection pool bukan detail kecil, tapi bagian dari arsitektur sistem.
Di Go:
- Goroutine murah
- Connection database mahal
Tanpa konfigurasi pool yang benar:
- Aplikasi terlihat scalable
- Database jadi single point of failure
Dengan connection pool yang tepat:
- Sistem stabil
- Latency konsisten
- Database lebih awet di production
Rule of thumb: Lebih baik request menunggu koneksi daripada database mati.