Connection Pooling di Distributed System
Studi Kasus: AWS Lambda + RDS dengan RDS Proxy
Pada sistem monolith tradisional, connection pool relatif mudah dikontrol. Namun di distributed system, terutama yang serverless seperti AWS Lambda, konsep pooling berubah total.
Jika kamu menerapkan pola lama secara naif, hasilnya hampir pasti:
- Database overload
- Connection exhaustion
- Latency spike yang sulit diprediksi
Artikel ini membahas mengapa pooling klasik gagal di distributed system, dan bagaimana RDS Proxy menjadi solusi resmi AWS untuk kasus Lambda + RDS.
Masalah Utama Pooling di Distributed System
Pooling Asumsi Klasik (Sudah Tidak Berlaku)
Pooling tradisional berasumsi:
- Aplikasi long-lived
- Jumlah instance terkontrol
- Setiap instance punya pool sendiri
Di distributed system modern:
- Instance bisa autoscale
- Bisa ada ratusan / ribuan instance
- Lifecycle instance pendek
- Tidak ada “global pool”
Kenapa Lambda + RDS Itu Berbahaya Tanpa Proxy?
Cara Lambda Bekerja (Penting Dipahami)
Lambda bisa scale ke ratusan instance
Setiap instance:
- Punya runtime sendiri
- Punya memory sendiri
- Punya connection pool sendiri
Artinya:
1 Lambda invocation ≠ 1 koneksi
1 Lambda instance → bisa membuka banyak koneksi
Jika:
- 500 concurrent Lambda
- Masing-masing buka 2–5 koneksi
➡️ Database langsung kehabisan connection
Masalah Umum Tanpa RDS Proxy
- Connection storm saat cold start.
- Idle connection menumpuk.
- Database max_connections tercapai.
- Lambda timeout padahal DB sehat.
Ini sangat sering terjadi di production.
Kenapa Connection Pool di Lambda Tidak Efektif?
Meskipun kamu pakai:
- GORM
- database/sql
- pooling di level code
Masalahnya:
- Pool hidup per Lambda instance
- Lambda instance tidak bisa sharing pool
- Instance bisa mati kapan saja
Kesimpulan penting: Connection pooling di Lambda level itu tidak cukup.
RDS Proxy: Pooling di Level Infrastruktur
Apa Itu RDS Proxy?
RDS Proxy adalah managed database proxy dari AWS yang:
- Berdiri di antara Lambda dan RDS
- Menyediakan shared connection pool
- Mengelola koneksi secara terpusat
Arsitektur:
Lambda
↓
RDS Proxy ←── global connection pool
↓
RDS (MySQL / PostgreSQL)
Apa yang Diselesaikan RDS Proxy?
- Mengurangi jumlah koneksi ke RDS ✅
- Menyerap spike Lambda concurrency ✅
- Reuse koneksi lintas Lambda instance ✅
- Lebih aman (IAM + Secrets Manager) ✅
Perbedaan Tanpa vs Dengan RDS Proxy
Tanpa RDS Proxy
Lambda A → DB (5 conn)
Lambda B → DB (5 conn)
Lambda C → DB (5 conn)
...
➡️ Connection tidak terkontrol
Dengan RDS Proxy
Lambda A → Proxy → DB
Lambda B → Proxy → DB
Lambda C → Proxy → DB
➡️ Proxy yang mengatur pool, bukan Lambda
Step-by-Step Setup RDS Proxy (Lambda + RDS)
Prasyarat
- RDS MySQL / PostgreSQL
- AWS Secrets Manager (untuk credential DB)
- Lambda function
- VPC + subnet
Simpan Credential DB di Secrets Manager
Buka AWS Secrets Manager
Create secret:
- Type: RDS database credentials
- Username & password DB
Simpan dan catat Secret ARN
Buat RDS Proxy
Buka RDS → Proxies
Create proxy
Isi:
Engine: MySQL / PostgreSQL
Target group: RDS instance / cluster
Authentication:
- Secrets Manager (pilih secret tadi)
IAM role:
- Allow proxy access Secrets Manager
Catat:
Proxy endpoint Contoh:
mydb-proxy.proxy-xyz.ap-southeast-1.rds.amazonaws.com
Atur Connection Pooling di RDS Proxy
Di Proxy target group:
Max connections (%):
- Biasanya 80–90%
Idle client timeout:
- Misal 30 menit
Ini adalah pool utama yang akan melindungi database.
Pastikan Lambda dan Proxy di VPC yang Sama
Lambda harus:
- Menggunakan VPC
- Subnet yang bisa akses RDS Proxy
Security Group:
- Lambda → RDS Proxy (allow inbound)
Update Lambda Environment Variable
Gunakan endpoint RDS Proxy, bukan RDS langsung:
DB_HOST=mydb-proxy.proxy-xyz.ap-southeast-1.rds.amazonaws.com
DB_PORT=5432
DB_NAME=app_db
Kode Golang (Contoh dengan GORM)
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
os.Getenv("DB_HOST"),
os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"),
os.Getenv("DB_NAME"),
os.Getenv("DB_PORT"),
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
⚠️ Catatan penting:
- Pool di code tetap diset kecil
- RDS Proxy yang jadi pengatur utama
Set Pool di Lambda (Minimal)
sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(2)
sqlDB.SetMaxIdleConns(1)
sqlDB.SetConnMaxLifetime(5 * time.Minute)
Kenapa kecil?
- Karena pooling sudah di-handle RDS Proxy
- Lambda instance tidak perlu banyak koneksi
Best Practice Angka Pooling (Lambda + RDS Proxy)
Di Lambda (per instance)
MaxOpenConns: 1–2MaxIdleConns: 0–1- Lifetime pendek
Di RDS Proxy
- Max connections: 80–90% dari DB limit
- Idle timeout: 15–30 menit
Observability & Debugging
Pantau:
CloudWatch:
- DatabaseConnections (RDS)
- Proxy metrics
Jika:
- Lambda timeout
- Tapi DB connection stabil
➡️ Artinya proxy bekerja dengan benar
Kapan RDS Proxy Wajib Dipakai?
- Lambda + RDS ✅
- High concurrency ✅
- Traffic spike tidak terduga ✅
- Banyak service ke satu database ✅
❌ Tidak wajib untuk:
- EC2 monolith
- Service dengan instance tetap & pool terkontrol
Penutup
Di distributed system:
Pooling bukan lagi tanggung jawab aplikasi, tapi infrastruktur.
Lambda + RDS tanpa RDS Proxy adalah:
- Bom waktu
- Masalahnya muncul saat traffic naik
- Sulit direproduksi di staging
Dengan RDS Proxy:
- Pooling terpusat
- Database terlindungi
- Sistem jauh lebih stabil
Rule of thumb: Serverless butuh server-side pooling.