Connection Pooling

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:

  1. Initial Pool Size Jumlah koneksi yang dibuat saat aplikasi start

  2. Max Pool Size Batas maksimum koneksi yang boleh dibuat

  3. Idle Connection Koneksi yang sedang tidak digunakan

  4. Borrow & Return Mechanism

    • Request meminjam koneksi
    • Setelah selesai, koneksi dikembalikan
  5. 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) #

  1. Sesuaikan pool size dengan workload

    • CPU-bound app → pool kecil
    • IO-bound app → pool sedang
  2. Rule of thumb awal

    max_pool ≈ (CPU core * 2) + effective concurrent query
    
  3. Selalu close / return connection

    • Jangan simpan connection di global state
    • Jangan pass connection antar goroutine / thread tanpa kontrol
  4. Gunakan timeout

    • Pool timeout
    • Query timeout
  5. 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 #

  1. Pool size = max DB connection
  2. Tidak pakai timeout
  3. Connection leak (tidak dikembalikan)
  4. Long transaction di high traffic endpoint
  5. Scaling app tanpa scaling database

Ringkasan #

AspekNon-DistributedDistributed
Pool scopePer aplikasiPer instance
RisikoUnder/over poolConnection explosion
Pool sizeLebih fleksibelHarus kecil
KompleksitasRendahTinggi
Best toolNative poolExternal 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.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact