Proxy Cache

Proxy Cache #

Nginx bisa menyimpan response dari backend ke disk dan melayaninya langsung tanpa menghubungi backend lagi untuk request berikutnya. Ini bisa secara dramatis mengurangi beban backend dan mempercepat response time untuk konten yang tidak sering berubah.

Menyiapkan Cache Zone #

Sebelum menggunakan cache, kamu perlu mendefinisikan zone cache di level http:

http {
    # path: direktori penyimpanan cache
    # levels=1:2: struktur subdirektori (mencegah terlalu banyak file dalam satu direktori)
    # keys_zone=nama:ukuran: nama zone dan ukuran shared memory untuk index
    # max_size: batas total ukuran cache di disk
    # inactive: hapus entry yang tidak diakses selama waktu ini
    # use_temp_path=off: tulis langsung ke direktori cache (lebih efisien)
    proxy_cache_path /var/cache/nginx
                     levels=1:2
                     keys_zone=main_cache:10m
                     max_size=1g
                     inactive=60m
                     use_temp_path=off;
}

keys_zone=main_cache:10m membuat area 10MB di shared memory untuk menyimpan index cache (key → metadata). 10MB bisa menyimpan sekitar 80.000 entry. Data aktual cache disimpan di disk.


Mengaktifkan Cache di Location #

server {
    location / {
        proxy_pass http://backend;

        # Gunakan zone cache yang sudah didefinisikan
        proxy_cache main_cache;

        # Cache response dengan status 200 dan 301 selama 1 jam
        proxy_cache_valid 200 301 1h;

        # Cache response 404 selama 1 menit
        proxy_cache_valid 404 1m;

        # Tambahkan header untuk debugging (hapus di production)
        add_header X-Cache-Status $upstream_cache_status;
    }
}

$upstream_cache_status bisa bernilai:

  • HIT — response dilayani dari cache
  • MISS — tidak ada di cache, request ke backend
  • BYPASS — cache di-bypass sesuai konfigurasi
  • EXPIRED — ada di cache tapi sudah expired, request ke backend untuk refresh
  • STALE — melayani cache lama karena backend error
  • UPDATING — entry sedang di-refresh oleh request lain

Cache Key: Apa yang Membedakan Entry Cache #

Nginx menentukan apakah dua request “sama” berdasarkan cache key. Default cache key adalah $scheme$proxy_host$request_uri.

Kamu bisa mengkustomisasi key ini:

location / {
    proxy_pass http://backend;
    proxy_cache main_cache;

    # Key default
    proxy_cache_key "$scheme$request_method$host$request_uri";

    # Jika konten berbeda berdasarkan Accept-Language header
    proxy_cache_key "$scheme$host$request_uri$http_accept_language";

    # Jika ada user yang login, jangan cache berdasarkan cookie
    # (lebih baik bypass cache untuk user terautentikasi)
}

Cache Bypass: Kapan Tidak Boleh Cache #

Tidak semua request boleh di-cache. Ada kondisi di mana Nginx harus selalu minta ke backend:

http {
    # Bypass cache jika ada cookie session (user terautentikasi)
    map $http_cookie $no_cache_cookie {
        default         0;
        ~*session_id    1;
        ~*auth_token    1;
    }

    # Bypass cache untuk method non-GET
    map $request_method $no_cache_method {
        default  0;
        POST     1;
        PUT      1;
        DELETE   1;
        PATCH    1;
    }
}

server {
    location / {
        proxy_pass http://backend;
        proxy_cache main_cache;
        proxy_cache_valid 200 1h;

        # Bypass jika salah satu kondisi terpenuhi
        proxy_cache_bypass $no_cache_cookie $no_cache_method;

        # Jangan simpan ke cache jika kondisi terpenuhi
        proxy_no_cache $no_cache_cookie $no_cache_method;

        # Bypass jika ada header Cache-Control: no-cache dari klien
        proxy_cache_bypass $http_cache_control;
    }
}

Stale Cache: Melayani Cache Lama Saat Backend Error #

Nginx bisa dikonfigurasi untuk melayani cache yang sudah expired ketika backend tidak bisa dihubungi — lebih baik menampilkan konten sedikit lama daripada error 502:

location / {
    proxy_pass http://backend;
    proxy_cache main_cache;
    proxy_cache_valid 200 1h;

    # Layani cache lama jika backend error/timeout/updating
    proxy_cache_use_stale error timeout updating
                          http_500 http_502 http_503 http_504;

    # Berapa lama boleh melayani stale cache
    proxy_cache_lock on;
    proxy_cache_lock_timeout 5s;
}

proxy_cache_lock on mencegah banyak request ke backend sekaligus untuk refresh satu entry cache yang expired — hanya satu yang dikirim ke backend, yang lain menunggu.


Header Cache dari Backend #

Nginx juga menghormati header cache standar HTTP dari backend:

# Di backend (contoh Node.js):
# res.set('Cache-Control', 'public, max-age=3600');
# res.set('Vary', 'Accept-Encoding');

# Nginx akan menggunakan max-age dari header ini
# Kamu bisa override dengan:
location /api/ {
    proxy_pass http://backend;
    proxy_cache main_cache;

    # Ignore header Cache-Control dari backend, gunakan konfigurasi Nginx
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid 200 30m;
}

Membersihkan Cache (Cache Purge) #

Nginx open-source tidak menyediakan purge endpoint bawaan (fitur ini ada di Nginx Plus). Tapi ada dua pendekatan umum:

Hapus file cache secara manual #

# Hapus semua cache
rm -rf /var/cache/nginx/*

# Reload agar Nginx tahu cache sudah bersih
nginx -s reload

Gunakan modul ngx_cache_purge #

# Dengan modul ngx_cache_purge (perlu dikompilasi)
location ~ /purge(/.*) {
    # Batasi akses purge ke IP internal saja
    allow 127.0.0.1;
    allow 10.0.0.0/8;
    deny all;

    proxy_cache_purge main_cache "$scheme$host$1";
}

# Panggil dengan:
# curl -X PURGE http://example.com/purge/api/products

Ringkasan #

  • Definisikan proxy_cache_path di level http sebelum bisa menggunakan cache di location.
  • $upstream_cache_status sebagai header debug untuk melihat apakah response dari cache (HIT) atau backend (MISS).
  • Gunakan proxy_cache_bypass dan proxy_no_cache untuk mencegah caching request yang terautentikasi atau method POST/PUT/DELETE.
  • proxy_cache_use_stale memungkinkan Nginx melayani cache lama saat backend down — berguna untuk resiliensi.
  • proxy_cache_lock on mencegah thundering herd saat banyak request datang bersamaan untuk cache yang expired.

← Sebelumnya: Buffer & Timeout   Berikutnya: Round Robin →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact