Connection Pooling & Application Performance
Mengelola connection pool database, PgBouncer, HTTP keep-alive, timeout, dan pola aplikasi yang menjaga performa.
Membuka koneksi baru untuk setiap request mahal. Connection pooling memakai ulang koneksi agar aplikasi lebih cepat dan database tidak kehabisan koneksi.
Mengapa pooling penting?
| Tanpa pool | Dengan pool |
|---|---|
| Handshake baru setiap query | Koneksi dipakai ulang |
| Overhead CPU/TLS | Overhead rendah |
| Mudah melebihi batas DB | Koneksi terkontrol |
| Latency lebih tinggi | Latency lebih stabil |
Pool di Node.js (PostgreSQL)
import pg from 'pg';
const pool = new pg.Pool({
host: process.env.DB_HOST,
port: 5432,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 10,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 5000,
statement_timeout: 10000,
});
export async function query(text, params) {
const client = await pool.connect();
try {
return await client.query(text, params);
} finally {
client.release();
}
}Selalu release() di finally agar koneksi tidak bocor.
Menghitung ukuran pool
total_koneksi = jumlah_instance_app × max_poolContoh: 4 instance × 10 = 40 koneksi. Pastikan max_connections database cukup, sisakan ruang
untuk admin dan job.
Jangan menambah instance tanpa menyesuaikan pool
Horizontal scaling menggandakan jumlah koneksi. Jika pool tidak diturunkan atau PgBouncer tidak dipakai, database bisa menolak koneksi.
PgBouncer
PgBouncer adalah connection pooler eksternal untuk PostgreSQL.
App instances ──▶ PgBouncer ──▶ PostgreSQL| Mode | Arti |
|---|---|
| Session | Satu koneksi per session |
| Transaction | Koneksi dilepas per transaksi |
| Statement | Koneksi dilepas per statement |
Transaction pooling paling umum untuk aplikasi web, tetapi tidak mendukung semua fitur session.
Konfigurasi ringkas:
[databases]
app = host=127.0.0.1 port=5432 dbname=app
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = scram-sha-256
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50Timeout
Timeout mencegah request menggantung selamanya.
| Timeout | Fungsi |
|---|---|
connectionTimeoutMillis | Batas menunggu koneksi |
statement_timeout | Batas query di database |
idleTimeoutMillis | Tutup koneksi idle |
| HTTP timeout | Batas request end-to-end |
Sesuaikan dengan latency normal; jangan terlalu ketat hingga memutus request valid.
HTTP keep-alive
Untuk panggilan ke API eksternal, gunakan keep-alive agar koneksi TCP/TLS dipakai ulang.
import https from 'node:https';
const agent = new https.Agent({ keepAlive: true, maxSockets: 50 });Redis pooling
Redis client biasanya mengelola koneksi sendiri. Gunakan satu client yang dibagikan, bukan membuat client baru per request.
import { createClient } from 'redis';
const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
export { redis };N+1 query
Masalah umum: satu query untuk daftar, lalu satu query per item.
// N+1
for (const order of orders) {
order.user = await db.getUser(order.user_id);
}
// Lebih baik: batch
const userIds = [...new Set(orders.map(o => o.user_id))];
const users = await db.getUsersByIds(userIds);Index database
CREATE INDEX CONCURRENTLY idx_orders_user_created
ON orders (user_id, created_at DESC);Gunakan EXPLAIN ANALYZE untuk memastikan index dipakai. Index mempercepat read, tetapi
memperlambat write dan memakan storage.
Backpressure
Jika queue atau worker lebih lambat dari producer, beri batas.
- Batasi concurrency.
- Gunakan queue dengan retry dan dead-letter.
- Tolak request dengan 429/503 saat kapasitas penuh.
Praktik: audit koneksi
# PostgreSQL
psql -c "select count(*), state from pg_stat_activity group by state;"
# Redis
redis-cli INFO clients
# Aplikasi
ss -tanp | grep :5432 | wc -lCari koneksi idle berlebih, koneksi menggantung, dan query lama.
Ringkasan
- Pooling mengurangi overhead dan mengontrol koneksi.
- Hitung total koneksi dari jumlah instance × pool.
- PgBouncer membantu saat banyak instance.
- Timeout, keep-alive, dan perbaikan query meningkatkan performa.
Selanjutnya
Pelajari database produksi di Production Database Architecture.