DEV Community

Cover image for Optimasi Arsitektur Database PostgreSQL dan Redis Caching untuk Menangani Beban Jutaan Kueri
Wahyu Andika Putra
Wahyu Andika Putra

Posted on Originally published at andikadev.com

Optimasi Arsitektur Database PostgreSQL dan Redis Caching untuk Menangani Beban Jutaan Kueri

Ringkasan Eksekutif (BLUF)

Menghadapi lonjakan lalu lintas ribuan permintaan per detik (requests per second) menuntut optimasi bertingkat pada lapisan basis data dan memori. Mengandalkan peningkatan kapasitas server vertikal (vertical scaling) memiliki batas efisiensi biaya. Solusi arsitektural yang berkelanjutan mengombinasikan optimasi kueri PostgreSQL melalui indexing presisi, mitigasi overhead koneksi dengan PgBouncer, dan penerapan pola Cache-Aside pada Redis cluster. Rekayasa backend berdaya tahan tinggi ini diterapkan dalam setiap pengembangan sistem di Andika Putra Dev.


1. Analisis Bottleneck Kueri dengan EXPLAIN (ANALYZE, BUFFERS)

Kesalahan paling umum dalam query tuning adalah menebak-nebak letak kelambatan tanpa membaca query execution plan. PostgreSQL menyediakan perintah komprehensif untuk mengungkap konsumsi I/O disk nyata:

-- Menganalisis kueri lambat secara mendalam
EXPLAIN (ANALYZE, BUFFERS, COSTS, VERBOSE)
SELECT o.id, o.total_amount, u.email, o.created_at
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.status = 'COMPLETED'
  AND o.created_at >= NOW() - INTERVAL '30 days'
ORDER BY o.created_at DESC
LIMIT 50;
Enter fullscreen mode Exit fullscreen mode

Indikator Kritis yang Wajib Diwaspadai:

  • Sequential Scan (Seq Scan): Membaca seluruh baris tabel secara linier karena tidak ada indeks yang cocok atau tabel terlalu besar. Pada tabel berkapasitas 10 juta baris, Seq Scan adalah penyebab utama CPU spike 100%.
  • Buffers: Read (Disk I/O): Mengindikasikan data harus dibaca langsung dari drive SSD alih-alih dari memori RAM (shared buffers).
  • Hash Join vs Nested Loop: Perhatikan cost estimasi penggabungan relasi antar-tabel.

2. Strategi Indexing Presisi: B-Tree, Partial Index, dan BRIN

Membuat indeks secara membabi-buta justru memperlambat operasi INSERT dan UPDATE. Pilih tipe indeks berdasarkan karakteristik data:

Jenis Indeks Kasus Penggunaan Ideal Efisiensi Ukuran Disk
B-Tree Standar Kolom unik, ID relasi, kesetaraan eksplisit (=) Menengah hingga Besar
Partial Index Kolom dengan distribusi data tidak seimbang (misal: WHERE is_deleted = false) Sangat Kecil & Cepat
BRIN (Block Range) Data berurutan kronologis (tabel audit log/timeseries miliaran row) Hingga 95% lebih hemat RAM dibanding B-Tree
GIN (Generalized Inverted) Pencarian Full-Text Search dan kolom JSONB Besar (Memerlukan maintenance)
-- Contoh Partial Index untuk order yang aktif saja
CREATE INDEX CONCURRENTLY idx_orders_active_completed 
ON orders (created_at DESC)
WHERE status = 'COMPLETED';
Enter fullscreen mode Exit fullscreen mode

3. Implementasi Caching Redis Pola Cache-Aside yang Tangguh

Untuk melindungi PostgreSQL dari thundering herd problem (lonjakan ribuan request membaca data yang sama secara bersamaan saat cache kedaluwarsa), terapkan pola Cache-Aside yang dilengkapi mutex lock / single-flight request:

// services/cacheService.ts
import Redis from 'ioredis';

const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379');

export async function getOrSetCache<T>(
  key: string,
  ttlSeconds: number,
  fetcher: () => Promise<T>
): Promise<T> {
  // 1. Cek keberadaan data di Redis
  const cached = await redis.get(key);
  if (cached) {
    return JSON.parse(cached) as T;
  }

  // 2. Jika miss, jalankan kueri ke database PostgreSQL
  const freshData = await fetcher();

  // 3. Simpan kembali ke Redis dengan jitter untuk mencegah cache stampede
  const jitter = Math.floor(Math.random() * 30);
  await redis.set(key, JSON.stringify(freshData), 'EX', ttlSeconds + jitter);

  return freshData;
}
Enter fullscreen mode Exit fullscreen mode

4. Efisiensi Arsitektur Connection Pooling dengan PgBouncer

Setiap koneksi langsung ke proses PostgreSQL mengonsumsi memori backend sekitar 10MB–20MB. Pada arsitektur microservices atau serverless functions yang membuka ratusan koneksi secara serentak, PostgreSQL akan mengalami out of memory (OOM).

Menempatkan PgBouncer dalam mode transaction pooling memungkinkan ribuan koneksi aplikasi client dilayani secara bergantian oleh hanya 50–100 koneksi fisik ke PostgreSQL, menghemat hingga 80% utilisasi RAM server.


Konsultasikan Arsitektur Sistem Skala Tinggi Anda

Membangun aplikasi dengan skalabilitas tinggi sejak hari pertama menghindarkan bisnis Anda dari downtime yang merugikan di masa mendatang.

Jika perusahaan Anda memerlukan konsultasi rekayasa backend, audit performa database, maupun pembuatan website berkecepatan tinggi, jadwalkan diskusi proyek sistem digital bersama tim software engineer di Andika Putra Dev.


Catatan Hak Cipta & Sumber Orisinal: Artikel teknis ini dipublikasikan secara orisinal di Andika Putra Dev. Kunjungi andikadev.com untuk konsultasi software engineering gratis dan solusi arsitektur cloud backend modern.

Top comments (0)