Caching Berlapis: Dari Browser, CDN, hingga Redis
Caching Bukan Satu Hal, Tapi Banyak Lapisan
Ketika orang bilang "tinggal di-cache aja", biasanya yang dimaksud adalah satu lapisan spesifik—padahal aplikasi web modern yang cepat biasanya memakai beberapa lapisan cache sekaligus, masing-masing menyelesaikan masalah yang berbeda dan menghemat kerja di lapisan yang ada di belakangnya.
Urutan lapisan dari yang paling dekat dengan pengguna:
Browser Cache -> CDN (Edge) -> Application Cache (Redis) -> Database Query Cache -> Database
Semakin dekat ke pengguna, semakin cepat responnya—tapi juga semakin sulit dikontrol invalidasinya.
Lapisan 1: Browser Cache
Ini lapisan termurah karena tidak butuh request jaringan sama sekali. Dikontrol lewat HTTP header Cache-Control.
Cache-Control: public, max-age=31536000, immutable # Aset statis dengan hash di nama file
Cache-Control: no-cache # Selalu revalidasi ke server (pakai ETag)
Cache-Control: private, max-age=0 # Jangan pernah cache (data sensitif per-user)
Pola paling efektif untuk aset seperti JS/CSS bundle: beri nama file dengan content hash (app.a1b2c3.js), lalu set max-age super panjang dengan immutable. Karena nama filenya berubah setiap kali isinya berubah, browser tidak akan pernah menyajikan versi basi—dan Anda dapat cache selama mungkin tanpa risiko.
Lapisan 2: CDN / Edge Cache
CDN menyimpan salinan response di lokasi geografis yang dekat dengan pengguna, mengurangi latensi jaringan dan beban ke origin server. Selain aset statis, CDN modern (Cloudflare, Vercel Edge, CloudFront) juga bisa cache HTML hasil render dan bahkan response API berdasarkan header cache yang sama.
Tantangan utamanya adalah invalidasi: begitu konten berubah di origin, CDN perlu tahu untuk membuang salinan lamanya. Dua pendekatan umum:
- Time-based (TTL): cache kedaluwarsa otomatis setelah durasi tertentu—sederhana, tapi ada jeda antara update dan saat semua edge node ter-refresh.
- Tag-based invalidation: tandai response dengan tag (misalnya
blog-post-123), lalu panggil endpoint purge spesifik untuk tag itu saat konten berubah—lebih presisi, didukung banyak CDN modern dan juga Next.js (revalidateTag).
Lapisan 3: Application-Level Cache (Redis)
Ini lapisan yang paling sering disebut developer ketika bicara "caching"—menyimpan hasil komputasi atau query yang mahal di in-memory store seperti Redis, di depan database.
Tiga pola paling umum:
Cache-Aside (Lazy Loading)—aplikasi mengecek cache dulu, kalau miss baru query database dan simpan hasilnya ke cache.
async function getPost(id: string) {const cached = await redis.get(`post:${id}`)if (cached) return JSON.parse(cached)const post = await db.query.posts.findFirst({ where: eq(posts.id, id) })await redis.set(`post:${id}`, JSON.stringify(post), "EX", 300)return post}
Write-Through—setiap kali data ditulis ke database, cache diperbarui bersamaan (bukan menunggu sampai ada yang membaca lagi). Lebih konsisten, tapi menambah latensi di jalur tulis.
Write-Behind—tulis ke cache dulu, lalu database diperbarui secara asinkron di belakang. Latensi tulis sangat rendah, tapi berisiko kehilangan data kalau proses asinkronnya gagal sebelum sempat tersimpan.
Masalah Klasik: Cache Stampede
Bayangkan sebuah cache key yang sangat populer tiba-tiba kedaluwarsa bersamaan saat traffic sedang tinggi—ribuan request datang secara bersamaan, semuanya mengalami cache miss, dan semuanya menghantam database secara serentak. Ini disebut cache stampede (atau thundering herd), dan bisa membuat database yang sehat tiba-tiba down karena lonjakan beban mendadak.
Mitigasi paling umum:
- Locking: hanya satu request yang boleh mengisi ulang cache; request lain menunggu hasilnya.
- Probabilistic early expiration: perbarui cache sedikit lebih awal dari waktu kedaluwarsa sebenarnya, dengan probabilitas yang meningkat mendekati waktu expired—sehingga refresh tersebar, tidak serentak.
- Stale-while-revalidate: tetap sajikan data lama sambil me-refresh di background—pengguna tidak pernah menunggu, dan tidak ada lonjakan beban mendadak.
Kesimpulan
Caching yang baik bukan soal menambahkan satu Redis instance dan berharap semuanya jadi cepat. Setiap lapisan—browser, CDN, aplikasi—punya peran, karakteristik invalidasi, dan trade-off konsistensi yang berbeda. Strategi yang matang mengombinasikan beberapa lapisan sekaligus, dengan pemahaman jelas: makin dekat ke pengguna, makin cepat tapi makin sulit dikontrol; makin jauh, makin lambat tapi makin mudah dijamin konsistensinya.
Artikel Terkait
Diskusi Pembaca (0)
Belum ada komentar. Jadilah yang pertama berdiskusi!
