Paket 2 · Praktik LanjutanModul E — Performance, Cache & Application Infrastructure

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 poolDengan pool
Handshake baru setiap queryKoneksi dipakai ulang
Overhead CPU/TLSOverhead rendah
Mudah melebihi batas DBKoneksi terkontrol
Latency lebih tinggiLatency 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_pool

Contoh: 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
ModeArti
SessionSatu koneksi per session
TransactionKoneksi dilepas per transaksi
StatementKoneksi 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 = 50

Timeout

Timeout mencegah request menggantung selamanya.

TimeoutFungsi
connectionTimeoutMillisBatas menunggu koneksi
statement_timeoutBatas query di database
idleTimeoutMillisTutup koneksi idle
HTTP timeoutBatas 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 -l

Cari 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.

On this page