All Products
Search
Document Center

:Konfigurasikan kebijakan cache HTTP Nginx

Last Updated:Dec 09, 2025

Konfigurasikan kebijakan cache HTTP pada server Nginx Anda untuk meningkatkan performa situs web. Kebijakan ini menginstruksikan browser dan proxy perantara, seperti Content Delivery Network (CDN), untuk menyimpan cache aset statis seperti gambar, file CSS, dan JS. Dengan caching tersebut, browser dapat memuat aset langsung dari salinan lokal alih-alih meminta ulang dari server, sehingga mempercepat waktu pemuatan halaman, mengurangi penggunaan bandwidth, serta meringankan beban server.

Contoh kebijakan cache umum

Bagian ini menyediakan konfigurasi caching umum yang dapat Anda tambahkan ke file konfigurasi Nginx untuk berbagai kasus penggunaan. Semua contoh menggunakan add_header ... always; untuk memastikan header cache ditambahkan ke semua respons, termasuk 304 Not Modified.

Kasus penggunaan 1: Tetapkan caching jangka panjang untuk sumber daya statis

# Tetapkan caching jangka panjang untuk sumber daya statis
# - Untuk nama file yang berisi hash konten (misalnya, main.a1b2c3d4.js), disarankan cache 1 tahun dengan immutable.
location ~* "\.[a-f0-9]{8,}\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$" {
    # Untuk sumber daya dengan hash yang dihasilkan oleh build tools: cache selama 1 tahun, browser tidak pernah melakukan revalidasi.
    add_header Cache-Control "public, max-age=31536003, immutable" always;
    access_log off;
}

# - Untuk nama file yang tetap dan jarang berubah (misalnya, logo.png), gunakan cache 30 hari.
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$ {
    # Untuk sumber daya statis umum tanpa hash: cache selama 30 hari, memungkinkan caching oleh CDN dan browser.
    add_header Cache-Control "public, max-age=2592000" always;
    access_log off;
}

Kasus penggunaan 2: Konfigurasikan kebijakan cache untuk dokumen HTML atau titik masuk Single-Page Application (SPA)

Jangan tetapkan cache jangka panjang untuk halaman HTML, terutama file entri SPA seperti index.html, karena kontennya berubah setiap kali ada Penerapan baru. Namun, untuk menyeimbangkan performa, Anda dapat mengizinkan browser menyimpan cache file tersebut dengan mewajibkannya melakukan revalidasi terhadap server sebelum setiap penggunaan.

# Untuk file HTML yang diminta langsung
location ~* \.html$ {
    # Mengizinkan caching oleh browser, tetapi mewajibkan revalidasi dengan server sebelum setiap penggunaan.
    # 'private' mencegah proxy perantara (seperti CDN) menyimpan cache respons ini.
    # Server harus menyediakan header ETag atau Last-Modified untuk mendukung validasi.
    add_header Cache-Control "private, no-cache, must-revalidate" always;
}
Catatan
  • Kebijakan ini bergantung pada server yang mengembalikan header respons ETag atau Last-Modified, yang memungkinkan browser membuat permintaan kondisional. Nginx menyediakan header ini untuk file statis secara default, sehingga tidak diperlukan konfigurasi tambahan.

  • Untuk mencegah proxy perantara, seperti CDN, menyimpan cache konten HTML, gunakan direktif private. Ini memastikan hanya browser pengguna akhir yang dapat menyimpan cache respons tersebut.

Kasus penggunaan 3: Nonaktifkan caching untuk konten dinamis atau informasi sensitif

Untuk konten yang dihasilkan secara dinamis atau berisi data sensitif—seperti endpoint API, halaman profil pengguna, atau halaman pembayaran—Anda harus menonaktifkan caching baik di browser maupun di semua proxy perantara, termasuk CDN dan cache bersama. Penonaktifan ini mencegah kebocoran informasi dan inkonsistensi data.

# Contoh: Untuk skrip PHP dinamis (sesuaikan path sesuai kebutuhan)
location ~ \.php$ {
    # ... Konfigurasi PHP-FPM lainnya ...

    # Nonaktifkan semua caching: Browser, proxy, dan CDN tidak boleh menyimpan respons.
    # 'no-store' adalah direktif kontrol cache paling ketat.
    add_header Cache-Control "no-store" always;
}

Konfigurasi cache sisi klien (mengontrol browser)

Anda dapat mengontrol perilaku cache browser pengguna dengan menambahkan header Cache-Control dan Expires ke respons HTTP. Praktik ini mengurangi permintaan jaringan dan mempercepat akses bagi pengguna akhir.

Direktif inti

  • Direktif expires: Menetapkan header Expires dan nilai max-age pada header Cache-Control.

    • Sintaks: expires [time|epoch|max|off];

    • Contoh: expires 30d; menyimpan cache selama 30 hari. expires -1; memaksa klien melakukan revalidasi sumber daya dengan server sebelum menggunakan versi yang di-cache. Ini setara dengan Cache-Control: no-cache tetapi tetap mengizinkan cache menyimpan sumber daya tersebut.

    • Catatan: Direktif add_header memberikan kontrol yang lebih granular dan merupakan metode konfigurasi yang direkomendasikan.

  • Direktif add_header: Menambahkan header HTTP tertentu ke respons.

    • Sintaks: add_header <name> <value> [always];

    • Deskripsi parameter always
      - Secara default, add_header hanya berlaku untuk respons 2xx dan 3xx.- Untuk respons 304 Not Modified, Nginx tidak secara otomatis menambahkan header kustom. Meskipun browser menggunakan kebijakan cache dari respons 200 awal, Anda harus menambahkan parameter always ke header kontrol cache agar header tersebut diterapkan ke semua kode status respons, memastikan kejelasan dan kompatibilitas.

Cache-Control deskripsi nilai kunci

  • public: Respons dapat di-cache oleh cache apa pun, termasuk browser, CDN, dan server proxy.

  • private: Hanya browser pengguna akhir yang dapat menyimpan cache respons. Cache bersama, seperti CDN, dilarang. Cocok untuk konten yang berisi informasi spesifik pengguna.

  • no-cache: Mengharuskan klien mengirim permintaan validasi ke server sebelum setiap penggunaan salinan yang di-cache. Jika sumber daya belum berubah, server mengembalikan 304 Not Modified, dan klien menggunakan cache lokal. Ini menghemat bandwidth.

  • no-store: Melarang browser dan server proxy menyimpan bagian mana pun dari respons. Cocok untuk data yang sangat sensitif.

  • max-age=<seconds>: Menetapkan periode validitas cache dalam detik.

  • immutable: Memberi tahu browser bahwa konten sumber daya tidak akan berubah selama masa kesegarannya. Browser kemudian dapat melewatkan permintaan validasi untuk sumber daya ini, bahkan saat pengguna melakukan refresh halaman penuh. Ideal untuk file yang namanya mengandung hash versi.

Deploy dan verifikasi

  1. Edit konfigurasi
    Tambahkan blok location ke blok server situs Anda. File konfigurasi biasanya berada di /etc/nginx/conf.d/ atau /etc/nginx/sites-enabled/.

  2. Muat ulang konfigurasi

    sudo nginx -t && sudo nginx -s reload
  3. Verifikasi header respons
    Gunakan curl untuk memeriksa apakah header cache aktif. Metode ini tidak terpengaruh oleh cache browser.

    curl -I http://your-domain.com/path/to/file.js

    Output harus mencakup header yang diharapkan, seperti Cache-Control: public, max-age=31536000.

  4. Verifikasi perilaku 304 (jika ETag atau no-cache dikonfigurasi)
    Uji dengan mengirim header validasi secara manual:

    ETAG=$(curl -I http://example.com/file.js 2>/dev/null | grep -i etag | cut -d' ' -f2 | tr -d '\r')
    curl -H "If-None-Match: $ETAG" -I http://example.com/file.js  # Harapkan respons 304
  5. Verifikasi di browser

    1. Buka Developer Tools → panel Network.

    2. Centang kotak Disable cache untuk melihat pemuatan awal (harus berstatus 200 OK).

    3. Hapus centang dan refresh halaman:

      1. Tidak ada permintaan atau ditampilkan from cache. Ini menunjukkan cache hit kuat.

      2. Ditampilkan 304. Ini menunjukkan cache hit kondisional.

FAQ

Mengapa perubahan Cache-Control Nginx saya tidak berlaku setelah memuat ulang konfigurasi?

Hal ini biasanya terjadi karena salah satu dari tiga alasan: respons lama sedang dilayani dari cache, Nginx belum benar-benar memuat ulang konfigurasi baru (sudo nginx -s reload), atau blok location lain memiliki prioritas lebih tinggi.

Untuk memecahkan masalah ini, ikuti langkah-langkah berikut:

  1. Verifikasi respons langsung dari server. Gunakan curl untuk melewati cache browser, CDN, atau proxy apa pun dan periksa header yang dikirim langsung dari server Anda.

    curl -I http://your-url

    Ini menunjukkan header Cache-Control yang sebenarnya dikirim oleh server.

  2. Pastikan konfigurasi Nginx telah dimuat ulang dengan sukses. Setelah melakukan perubahan, Anda harus menjalankan sudo nginx -s reload agar perubahan diterapkan.

  3. Periksa prioritas pencocokan blok location. Nginx memproses blok location dalam urutan tertentu. Permintaan mungkin cocok dengan aturan yang lebih umum secara tak terduga. Ingat bahwa pencocokan ekspresi reguler (seperti ~* \.(css|js)$) memiliki prioritas lebih tinggi daripada pencocokan awalan (seperti location /static/). Permintaan untuk /static/app.js bisa saja salah ditangani oleh aturan regex jika muncul dalam konfigurasi Anda.

Bagaimana cara mencegah Nginx menyimpan cache endpoint API dinamis yang cocok dengan aturan aset statis?

Hal ini terjadi ketika ekspresi reguler luas untuk aset statis, seperti ~* \.js$, juga cocok dengan path API dinamis, misalnya /api/user.js.

Untuk memperbaikinya, buat aturan location Anda lebih spesifik.

  1. Batasi path: location ~* ^/static/.*\.(css|js)$

  2. Pastikan blok location untuk antarmuka dinamis, seperti /api/ atau \.php$, memiliki prioritas pencocokan lebih tinggi atau secara eksplisit menonaktifkan caching.

Apa cara yang benar untuk menetapkan kebijakan Cache-Control berbeda untuk jenis file berbeda tanpa konflik blok location?

Menggunakan beberapa blok location untuk menetapkan kebijakan cache berdasarkan jenis file dapat menyebabkan konflik akibat prioritas pencocokan location Nginx. Solusi yang lebih bersih dan andal adalah menggunakan map untuk menentukan logika caching berdasarkan Content-Type respons.

Solusi: Gabungkan kebijakan tersebut. Anda dapat menggunakan map untuk menetapkan cache secara dinamis berdasarkan tipe konten:

# Di blok http
map $sent_http_content_type $cache_control {
    ~^image/    "public, max-age=2592000";
    text/css    "public, max-age=2592000";
    application/javascript "public, max-age=2592000";
    default     "no-cache";
}

# Di blok server
add_header Cache-Control $cache_control always;