Referensi cepat caching strategies untuk web developer. HTTP cache headers, CDN, browser cache, Service Worker, eviction policies, dan cache invalidation patterns.
Login atau daftar akun gratis untuk membaca cheat sheet ini.
4 pattern utama caching di application layer. Untuk implementasi code lengkap dengan Redis, lihat artikel /artikel/redis-untuk-caching.
Aplikasi cek cache dulu, kalau miss, fetch dari database dan simpan ke cache.
App --> [Cache hit?] --yes--> return cached
--no---> [Fetch DB] --> [Set Cache] --> returnKapan pakai: data yang read-heavy, jarang berubah. Default choice buat kebanyakan apps. Trade-off: cold cache miss = 3x latency (cek cache + query DB + set cache).
Cache layer yang otomatis fetch dari database kalau miss. Aplikasi cuma ngobrol sama cache library (contoh: cache-manager, Spring Cache).
App --> Cache Library --> [Cache hit?] --yes--> return
--no---> [Auto-fetch DB] --> [Set Cache] --> returnAplikasi ngga peduli cache ada atau ngga. Library handle semuanya.
Setiap write ke database juga write ke cache secara sinkron.
App --> [Write DB] --> [Write Cache] --> return (both updated)Kapan pakai: data yang sering dibaca setelah di-update. Konsistensi tinggi. Trade-off: write latency lebih tinggi (2x write operations).
Write ke cache dulu, database di-update asynchronously via queue.
App --> [Write Cache] --> return (fast!)
[Background worker: drain queue --> DB]Kapan pakai: high-write scenarios (metrics, analytics, counters) di mana toleransi data loss kecil.
| Pattern | Read Latency | Write Latency | Consistency | Complexity |
|---|---|---|---|---|
| Cache-Aside | High on miss | Low | Eventual | Low |
| Read-Through | Low | Low | Eventual | Medium |
| Write-Through | Low | High | Strong | Medium |
| Write-Behind | Low | Very Low | Weak | High |
Strategi invalidasi cache saat data berubah.
// Explicit invalidation
async function deleteUser(id) {
await db.query('DELETE FROM users WHERE id = $1', [id]);
await redis.del(`user:${id}`);
// Redis TTL
await redis.set('key', 'value', 'EX', 3600); // expire dalam 1 jam
await redis.set('key', 'value', 'PX'
Cache otomatis hapus item yang paling lama tidak diakses.
// Redis maxmemory dengan LRU
// redis.conf:
// maxmemory 256mb
// maxmemory-policy allkeys-lru
// Atau via command
// CONFIG SET maxmemory 256mb
// CONFIG SET maxmemory-policy allkeys-lru
// JavaScript LRU implementation
class LRUCache {
constructor
Hapus item yang paling jarang diakses berdasarkan frekuensi.
// Redis config
// maxmemory-policy allkeys-lfu
// LFU menggunakan probabilistic counter + decay
// Manual LFU di JavaScript
class LFUCache {
constructor(maxSize = 100) {
this.maxSize =
# Cache-Control (paling powerful)
Cache-Control: public, max-age=3600 # cache 1 jam
Cache-Control: private, max-age=0 # browser only, no CDN
Cache-Control: no-cache # revalidate setiap kali
Cache-Control: no-store # never cache
Cache-Control: max-age=31536000, immutable # 1 tahun, tidak akan berubah
// Next.js 16 Cache Components
import { unstable_cache } from 'next/cache';
// Cache function result
const getCachedUser = unstable_cache(
async (id) => {
return await db.user.findById
// Service Worker cache
const CACHE_NAME = 'app-v1';
const ASSETS = ['/', '/styles.css', '/app.js'];
self.addEventListener('install', (event) => {
// Cloudflare Page Rules (via Wrangler atau dashboard)
// Cache everything untuk API responses
{
"matches": ["api.example.com/*"],
"cache": {
"edgeTtl": 3600,
"browserTtl": 60
}
}
// Vercel Edge Config + cache
// Cache key yang baik: specific, hierarchical, versionable
// BAD: terlalu generik
redis.set('data', JSON.stringify(data));
// GOOD: namespaced + specific
redis.set('user:123:profile', JSON.stringify(data));
Pattern ini umum di sistem dengan Redis atau Memcached. Implementasi code lengkap ada di artikel /artikel/redis-untuk-caching.
Simpan session user di cache (bukan di memory server) buat horizontal scaling. Express + connect-redis, NextAuth + Upstash, atau Django + django-redis.
Fixed window (counter per period) atau sliding window (sorted set per timestamp). Cache sebagai single source of truth buat count across multiple server instances.
Mutex lock across multiple server instances pakai SET NX (set-if-not-exists). Release pakai Lua script buat atomic check-and-delete.
Saat cache miss bersamaan (1000 request datang bareng), pakai mutex lock biar cuma 1 request yang fetch dari DB. Request lain nunggu dan baca cache setelahnya.
Query buat data yang ngga ada di DB. Cache miss terus. Solusi: cache null result juga (dengan TTL pendek).
Banyak entry expire barengan. Solusi: randomize TTL (base_ttl + random(0, 60)).