HTTPQUERY
Bahasa Indonesia

Cache-Control

Penggunaan

Server asal, perantara, dan klien semuanya mengandalkan Cache-Control untuk menyepakati kapan sebuah respons yang tersimpan masih dapat digunakan dan kapan salinan baru dibutuhkan. Satu respons sering menggabungkan beberapa direktif untuk menyatakan kebijakan caching yang lengkap: berapa lama disimpan, siapa yang boleh menyimpan, dan apa yang harus dilakukan setelah masa kesegaran berakhir.

Tabel di bawah ini menunjukkan direktif mana yang berlaku untuk request, response, atau keduanya.

Beberapa direktif dipisahkan dengan koma dalam satu nilai header, atau dipecah ke dalam beberapa header Cache-Control. Ketika muncul direktif yang saling bertentangan, kombinasi yang paling ketat yang berlaku.

Catatan

Direktif yang tidak dikenali akan diabaikan oleh cache. Hal ini memungkinkan direktif baru diperkenalkan tanpa merusak implementasi lama.

Catatan

Ketika header Cache-Control tidak ada, cache menerapkan kesegaran heuristik. Heuristik yang umum adalah 10% dari rentang waktu sejak Last-Modified. Artinya, respons tanpa Cache-Control tetap akan di-cache oleh browser dan CDN. Menetapkan Cache-Control secara eksplisit mencegah perilaku caching yang tidak diinginkan.

Catatan

Cache-Control mengatur kapan harus melakukan revalidasi (masa kesegaran). ETag mengatur bagaimana melakukan revalidasi (identitas konten). Keduanya bekerja bersama: Cache-Control menentukan apakah revalidasi diperlukan, ETag menentukan apakah konten berubah. Header Pragma adalah padanan Cache-Control: no-cache pada HTTP/1.0 dan secara praktis sudah usang.

max-age

Direktif max-age memberi tahu cache untuk mengembalikan respons yang tersimpan hanya jika usia respons tersebut tidak melebihi jumlah detik yang ditentukan. Nilai yang tidak valid, misalnya angka negatif, diperlakukan sebagai 0.

Cache-Control: max-age=<seconds>

Menetapkan max-age=0 memaksa revalidasi ujung ke ujung. Pola ini berasal dari implementasi HTTP/1.0 yang belum mendukung no-cache.

max-stale

Direktif max-stale menandakan kesediaan menerima respons yang nilai Age-nya telah melampaui masa kesegaran hingga sejumlah detik yang diberikan. Jendela toleransi dimulai begitu max-age berakhir.

Cache-Control: max-stale=<seconds>

Direktif ini berguna ketika server asal untuk sementara tidak dapat dijangkau dan respons yang sedikit basi masih dapat diterima.

min-fresh

Direktif min-fresh meminta respons tersimpan yang sisa masa kesegarannya minimal sebanyak detik yang ditentukan. Cache hanya mengembalikan salinan tersimpan jika respons tersebut akan tetap segar selama periode tambahan itu.

Cache-Control: min-fresh=<seconds>

no-cache

Request yang membawa no-cache mewajibkan cache memvalidasi respons tersimpan ke server asal sebelum menyajikan salinannya. Hal ini memaksa revalidasi tanpa membuang entri yang tersimpan.

Cache-Control: no-cache

Catatan

Untuk mencegah cache menyimpan respons sama sekali, gunakan no-store sebagai gantinya.

no-store

Direktif no-store meminta cache untuk tidak menyimpan request maupun respons yang bersangkutan.

Cache-Control: no-store

no-transform

Direktif no-transform melarang perantara memodifikasi body respons, misalnya mengompresi ulang gambar atau mengonversi format media. Pembatasan ini berlaku baik perantara tersebut berupa proxy caching maupun gateway penerus.

Cache-Control: no-transform

only-if-cached

Direktif only-if-cached memberi tahu cache untuk mengembalikan respons tersimpan tanpa menghubungi server asal. Jika tidak ada respons tersimpan yang sesuai, cache mengembalikan status 504.

Cache-Control: only-if-cached

max-age

Direktif max-age menyatakan jumlah detik respons tetap segar setelah dibuat. Penghitung waktu dimulai sejak server asal membuat respons, sehingga waktu transit dan waktu yang dihabiskan di cache perantara ikut memotong anggaran waktu tersebut.

Cache-Control: max-age=<seconds>

Respons dengan max-age=3600 tetap segar selama satu jam. Setelah satu jam berlalu, cache memperlakukan respons sebagai basi lalu melakukan revalidasi atau mengambil salinan baru, bergantung pada direktif lain yang ada.

s-maxage

Direktif s-maxage (shared max-age) menggantikan max-age untuk cache bersama seperti CDN dan server proxy. Cache browser yang bersifat privat mengabaikan s-maxage dan kembali menggunakan max-age.

Cache-Control: s-maxage=<seconds>

no-cache

Direktif no-cache pada respons mewajibkan cache melakukan revalidasi respons tersimpan ke server asal sebelum setiap kali digunakan kembali. Cache tetap menyimpan respons tersebut, sehingga memungkinkan request bersyarat dengan ETag atau Last-Modified.

Cache-Control: no-cache

Ketika no-cache menyertakan daftar nama field, hanya header tertentu itulah yang memerlukan revalidasi. Sisa respons tersimpan disajikan tanpa menghubungi server asal.

Cache-Control: no-cache="Set-Cookie"

Catatan

Untuk mencegah penyimpanan sepenuhnya, gunakan no-store.

no-store

Direktif no-store mencegah cache mana pun menyimpan respons. Setiap request berikutnya diteruskan ke server asal.

Cache-Control: no-store

Catatan

no-cache mengizinkan penyimpanan, tetapi mewajibkan revalidasi sebelum setiap penggunaan. Cache memeriksa ke server asal melalui If-None-Match atau If-Modified-Since dan menerima 304 jika konten tidak berubah. no-store mencegah penyimpanan sepenuhnya, sehingga tidak ada salinan yang disimpan dan setiap request mengambil respons utuh. Kesalahan yang umum adalah menggunakan no-cache padahal yang dimaksudkan adalah no-store untuk data sensitif seperti catatan perbankan atau rekam medis. no-cache efisien untuk konten yang sering diperbarui. no-store diperuntukkan bagi konten yang tidak boleh sama sekali tersimpan di disk.

no-transform

Direktif no-transform pada respons mencegah perantara mengubah body respons sebelum meneruskannya, terlepas dari apakah perantara tersebut melakukan caching atas konten itu atau tidak.

Cache-Control: no-transform

must-revalidate

Direktif must-revalidate mengizinkan cache menyajikan respons selama masih segar. Setelah basi, cache menghubungi server asal untuk melakukan revalidasi sebelum menyajikan respons itu lagi. Jika server asal tidak dapat dijangkau, cache mengembalikan 504 alih-alih menyajikan konten basi.

Cache-Control: must-revalidate

proxy-revalidate

Direktif proxy-revalidate bekerja persis seperti must-revalidate, hanya saja ketentuannya berlaku khusus untuk cache bersama. Cache browser yang bersifat privat tidak terpengaruh.

Cache-Control: proxy-revalidate

must-understand

Direktif must-understand menginstruksikan cache untuk menyimpan respons hanya jika cache tersebut mengenali kode status dan memahami persyaratan caching yang terkait.

Cache-Control: must-understand, no-store

Memasangkan must-understand dengan no-store menyediakan mekanisme cadangan: cache yang tidak mendukung must-understand akan mengabaikan direktif yang tidak dikenal itu dan justru mematuhi no-store.

private

Direktif private membatasi penyimpanan hanya pada cache privat, biasanya browser pengguna akhir. Cache bersama seperti CDN dan server proxy akan membuang respons tersebut.

Cache-Control: private

public

Direktif public menandai sebuah respons sebagai layak disimpan di cache bersama. Respons yang membawa header Authorization tidak disimpan oleh cache bersama kecuali direktif public hadir.

Cache-Control: public

Catatan

Direktif public tidak diperlukan ketika must-revalidate atau s-maxage sudah ada.

immutable

Direktif immutable menjamin body respons tidak akan berubah selama masa kesegaran. Cache melewati request bersyarat untuk sumber daya yang immutable, sehingga menghilangkan perjalanan bolak-balik revalidasi untuk aset seperti bundel JavaScript berversi atau gambar ber-fingerprint.

Cache-Control: public, max-age=31536000, immutable

stale-while-revalidate

Direktif stale-while-revalidate memperpanjang jendela kegunaan sebuah respons basi. Setelah masa kesegaran berakhir, cache menyajikan salinan basi sambil melakukan revalidasi di latar belakang. Parameternya menentukan berapa detik tambahan respons basi tersebut masih dapat diterima.

Cache-Control: max-age=600, stale-while-revalidate=30

Begitu revalidasi di latar belakang selesai, cache mengganti entri basi dengan respons yang segar. Pola ini menyembunyikan latensi revalidasi dari pengguna akhir.

stale-if-error

Direktif stale-if-error mengizinkan cache menyajikan respons basi ketika server asal mengembalikan status error (500, 502, 503, atau 504) atau tidak dapat dijangkau. Parameternya menetapkan jumlah detik di luar masa kesegaran selama respons basi masih dapat digunakan sebagai cadangan.

Cache-Control: max-age=600, stale-if-error=86400

Contoh

Sebuah aset statis yang disajikan dengan masa kesegaran panjang dan flag immutable. Browser dan cache bersama mana pun menyimpan respons ini selama satu tahun tanpa revalidasi.

Cache-Control: public, max-age=31536000, immutable

Sebuah respons API yang hanya ditujukan untuk browser yang mengirim request. Cache menyimpan respons selama lima menit dan melakukan revalidasi sebelum digunakan kembali setelah basi.

Cache-Control: private, max-age=300, must-revalidate

Sebuah kebijakan yang ditujukan untuk CDN, memberi cache bersama jendela sepuluh menit sementara cache browser mendapat satu menit. Respons basi disajikan hingga 30 detik sementara CDN melakukan revalidasi di latar belakang.

Cache-Control: s-maxage=600, max-age=60, stale-while-revalidate=30

Googlebot dan max-age

Infrastruktur perayapan Google menerapkan caching HTTP secara heuristik. Direktif max-age membantu Googlebot menentukan frekuensi perayapan ulang. Halaman dengan max-age panjang diambil ulang lebih jarang, sedangkan no-cache menandakan konten yang sering berubah dan layak dirayapi lebih sering. Respons tanpa header cache apa pun secara bawaan dapat di-cache secara heuristik untuk kode status tertentu, sehingga server asal yang ingin mencegah caching sepenuhnya perlu mengirim no-store secara eksplisit. Bingbot mengirim Cache-Control: no-cache pada request dan mengandalkan crawl-delay di robots.txt serta IndexNow untuk mengatur laju perayapan.

Catatan

Untuk bantuan SEO dan caching, hubungi konsultan SEO mantan Google, Search Brothers.

Pemecahan masalah

Perilaku caching yang tidak diharapkan berasal dari kesalahpahaman direktif, penimpaan oleh CDN, atau header yang saling bertentangan.

Konten basi tetap disajikan meskipun ada direktif no-cache. Direktif no-cache tidak mencegah penyimpanan. Cache tetap menyimpan respons dan melakukan revalidasi pada setiap penggunaan ulang. Untuk mencegah penyimpanan sepenuhnya, gunakan no-store. Gabungkan keduanya bila melibatkan data sensitif: Cache-Control: no-cache, no-store.

CDN mengabaikan direktif Cache-Control. Banyak CDN menimpa Cache-Control dari server asal dengan kebijakan mereka sendiri. Cloudflare secara bawaan menghormati header dari server asal, tetapi menimpanya ketika Page Rule atau Cache Rule aktif. AWS CloudFront menggunakan header server asal kecuali bila dilampirkan kebijakan cache dengan TTL kustom. Periksa aturan penimpaan di dasbor CDN sebelum men-debug konfigurasi server asal.

Konten basi masih bertahan setelah max-age diturunkan. Node edge CDN dan cache browser mempertahankan respons sampai max-age aslinya berakhir. Menurunkan nilainya di server asal tidak menghapus salinan yang sudah ter-cache. Lakukan purge CDN setelah mengubah masa berlaku cache. Di Cloudflare, lakukan purge per URL atau gunakan purge seluruh zona. Di CloudFront, buat invalidation untuk path yang terdampak.

Browser menampilkan halaman lama saat navigasi maju/mundur meskipun ada no-store. Cache maju/mundur (bfcache) di Chrome, Firefox, dan Safari memulihkan seluruh state halaman dari memori, melewati no-store. Perilaku ini memang disengaja dan bukan merupakan pelanggaran cache. Periksa header Cache-Control di tab Network DevTools dengan “Disable cache” tidak dicentang untuk memastikan header tersebut sampai ke browser. Menambahkan listener event unload akan menonaktifkan bfcache di sebagian browser, tetapi menurunkan performa.

Header Expires bertentangan dengan Cache-Control. Ketika kedua header hadir, Cache-Control: max-age lebih diutamakan daripada Expires. Hapus header Expires untuk menghindari kebingungan. Di nginx:

expires off;
add_header Cache-Control "max-age=3600";

Di Apache:

Header unset Expires
Header set Cache-Control "max-age=3600"

Mendiagnosis header cache dengan curl dan DevTools. Jalankan curl -I https://example.re untuk memeriksa header respons dari server asal. Tambahkan -H “Cache-Control: no-cache” untuk melewati cache CDN dan langsung mencapai server asal. Di DevTools browser, buka tab Network, pilih request tersebut, lalu periksa bagian Response Headers. Perhatikan header Age, X-Cache, dan CF-Cache-Status untuk menentukan apakah respons berasal dari node edge CDN atau dari server asal.