Caching Strategies — System Design

Caching menyimpan data yang sering diakses di tempat yang lebih cepat, mengurangi beban database dan mempercepat response. Di mana cache bisa ditaruh: Client (B

Caching menyimpan data yang sering diakses di tempat yang lebih cepat, mengurangi beban database dan mempercepat response.

Di mana cache bisa ditaruh:

Client (Browser) → CDN → Load Balancer → App Server → Cache (Redis) → Database
      ↑                                      ↑              ↑
  Browser cache                        App-level cache  DB query cache

Caching patterns:

1. Cache-Aside (Lazy Loading) Paling umum. App cek cache dulu, jika miss baru query database, lalu simpan di cache.

async function getUser(userId) {
  // 1. Cek cache
  const cached = await redis.get("user:" + userId);
  if (cached) return JSON.parse(cached); // Cache hit!

  // 2. Cache miss — query database
  const user = await db.query("SELECT * FROM users WHERE id = ?", [userId]);

  // 3. Simpan di cache (TTL 1 jam)
  await redis.set("user:" + userId, JSON.stringify(user), "EX", 3600);

  return user;
}

Kelebihan: hanya data yang dibutuhkan yang di-cache Kekurangan: cache miss pertama selalu lambat, data bisa stale

2. Write-Through Data ditulis ke cache dan database secara bersamaan.

async function updateUser(userId, data) {
  // Tulis ke database
  await db.query("UPDATE users SET ... WHERE id = ?", [userId]);

  // Tulis ke cache juga
  await redis.set("user:" + userId, JSON.stringify(data), "EX", 3600);
}

Kelebihan: cache selalu up-to-date Kekurangan: setiap write lebih lambat (2 operasi), cache bisa berisi data yang jarang dibaca

3. Write-Behind (Write-Back) Data ditulis ke cache dulu, database di-update secara asinkron.

Write → Cache (instant) → Queue → Database (later)

Kelebihan: write sangat cepat Kekurangan: risiko kehilangan data jika cache crash sebelum sync ke database

4. Read-Through Mirip cache-aside tapi cache-nya yang bertanggung jawab mengambil data dari database (bukan app).

Cache eviction policies: Ketika cache penuh, data lama harus dihapus:

Policy Strategi
LRU Hapus yang paling lama tidak diakses (paling umum)
LFU Hapus yang paling jarang diakses
FIFO Hapus yang paling dulu masuk
TTL Hapus berdasarkan waktu hidup

Cache invalidation: Salah satu masalah tersulit di computer science: kapan menghapus cache?

// Strategi 1: TTL (Time to Live) — expired otomatis
await redis.set("key", value, "EX", 3600); // hapus setelah 1 jam

// Strategi 2: Event-based — hapus saat data berubah
async function updateArticle(id, data) {
  await db.updateArticle(id, data);
  await redis.del("article:" + id);         // hapus cache spesifik
  await redis.del("article-list");           // hapus cache list juga
}

// Strategi 3: Version-based
await redis.set("articles:v2", data); // ganti key saat data berubah

Thundering herd problem: Jika cache expired dan 1000 request datang bersamaan, semua akan query database.

Solusi: lock — hanya satu request yang query database, sisanya tunggu cache di-refresh.

Redis vs Memcached:

Aspek Redis Memcached
Data types String, list, set, hash, dll Hanya string
Persistence Bisa persist ke disk Hanya memory
Pub/Sub Ada Tidak ada
Popularitas Lebih populer Sederhana dan cepat

🎭 Analogi sehari-hari: Cache = laci atas meja kerja. Pulpen yang sering dipakai taruh di laci (cepat ambil). Yang jarang dipakai di gudang (database). Mau ambil pulpen? Cek laci dulu. Gak ada? Buka gudang, ambil, simpan di laci untuk next time. Itulah Cache-Aside.

💡 "There are only 2 hard things in CS: cache invalidation and naming things" — Phil Karlton. Cache invalidation susah karena: kapan invalidate? key apa yang affected? race condition antara update DB dan invalidate? Strategi paling aman: TTL pendek (5-15 menit) + invalidate eksplisit untuk operasi critical.

⚠️ Jebakan klasik:

🎯 Pilih cache pattern:

TL;DR: Cache = simpan data di tempat lebih cepat (Redis/Memcached/CDN/browser). Cache-Aside paling umum. Wajib strategi invalidation. Awas thundering herd, hot key, stampede. TTL + event invalidation = balance.

Yang akan kamu pelajari