Cache-Control — apa itu, direktif dan manajemen caching

Penulis: IT Sectr Diterbitkan: 2026-03-09 Waktu membaca: 9 mnt

Cache-Control — header HTTP yang menentukan aturan caching sumber daya di sisi klien, server proxy, dan CDN menggunakan serangkaian direktif. Berbeda dengan header Expires yang sudah usang, Cache-Control mendukung puluhan kombinasi: max-age menetapkan waktu hidup dalam detik, private dan public mengelola ketersediaan cache, no-cache dan no-store — pemeriksaan paksa. Menurut Google Web Dev (2025), konfigurasi Cache-Control yang tepat dapat mengurangi waktu muat halaman sebesar 50-80% untuk kunjungan berulang. Ini menjadikan header tersebut penting untuk kinerja aplikasi web dan seluler.

Poin Utama

  • Cache-Control — header HTTP dengan direktif yang mengelola caching di klien, proxy, dan CDN
  • max-age — direktif kunci yang menetapkan waktu hidup sumber daya dalam detik tanpa pemeriksaan ulang
  • private vs public — private mengizinkan cache hanya di klien, public juga di proxy dan CDN
  • no-cache vs no-store — no-cache memerlukan pemeriksaan sebelum digunakan, no-store melarang caching sepenuhnya
  • s-maxage — menggantikan max-age untuk cache bersama (shared), tanpa memengaruhi browser

Apa itu Cache-Control?

Cache-Control — header HTTP, distandarisasi dalam HTTP/1.1 (RFC 7234), yang memungkinkan server menentukan bagaimana dan berapa lama klien, proxy, dan CDN dapat menyimpan respons dalam cache. Berbeda dengan Expires (HTTP/1.0), Cache-Control menggunakan direktif — perintah teks yang digabungkan dengan koma: Cache-Control: public, max-age=3600, must-revalidate. Header ini memberikan kontrol yang presisi atas setiap mata rantai dalam rantai caching.

Caching adalah salah satu mekanisme fundamental kinerja web dan aplikasi seluler. Tanpanya, setiap permintaan pengguna akan langsung menuju server, menyebabkan beban berlebih dan keterlambatan. Cache-Control mendefinisikan tiga tingkat caching: browser/aplikasi (private cache), server proxy (shared cache), dan CDN (distributed cache). Setiap tingkat menafsirkan direktif dengan caranya sendiri.

Konfigurasi Cache-Control yang salah adalah salah satu penyebab paling umum masalah kinerja. Caching yang terlalu agresif menyebabkan pengguna melihat data usang. Caching yang terlalu lemah menyebabkan permintaan berlebihan ke server dan pemuatan lambat. Menurut Akamai (2025), optimalisasi Cache-Control untuk konten statis mengurangi beban server sebesar 70-90% dan meningkatkan waktu muat sebesar 40-60% untuk pengguna seluler.

Sejarah header

Cache-Control muncul di HTTP/1.1 (RFC 2616, 1999) sebagai pengganti Expires. Expires memiliki masalah mendasar: menggunakan tanggal absolut yang bergantung pada zona waktu server dan klien. Cache-Control memecahkan masalah ini dengan beralih ke waktu relatif (max-age dalam detik sejak saat menerima respons). Kemudian dalam RFC 7234 (2014) ditambahkan direktif baru: immutable untuk statis, stale-while-revalidate dan stale-if-error untuk pemeriksaan tertunda.

Direktif Cache-Control

Cache-Control mencakup lebih dari 10 direktif yang dibagi menjadi tiga kelompok: direktif permintaan (klien → server), direktif respons (server → klien), dan ekstensi. Dalam praktiknya, dalam pengembangan seluler digunakan 6-7 direktif respons dasar yang mencakup 95% skenario caching. Mari kita bahas masing-masing dengan contoh dan rekomendasi.

DirektifArtiContoh
max-ageWaktu hidup dalam detik sejak responsmax-age=3600 — 1 jam
s-maxagemax-age untuk shared cache (proxy, CDN)s-maxage=86400 — 1 hari untuk CDN
publicMengizinkan caching kepada semua orang (termasuk proxy)public, max-age=3600
privateMengizinkan cache hanya untuk browser/aplikasiprivate, max-age=600
no-cacheJangan gunakan tanpa pemeriksaan (304 wajib)no-cache
no-storeLarang caching sepenuhnyano-store
must-revalidateSetelah max-age, wajib periksa ke originmax-age=3600, must-revalidate
immutableSumber daya tidak akan berubah (untuk statis yang diberi versi)max-age=31536000, immutable

max-age — direktif terpenting. Ini melarang klien mengirim permintaan ke server untuk jangka waktu tertentu. Untuk statis (CSS, JS, gambar) max-age biasanya diatur dari 1 hari hingga 1 tahun. Untuk respons API — dari 0 detik (data selalu segar) hingga 5-10 menit (data referensi). s-maxage memungkinkan pengaturan waktu hidup yang berbeda untuk CDN dan browser: CDN menyimpan salinan 1 hari, browser — 1 jam.

no-cache vs no-store

Kedua direktif ini sering tertukar. no-cache tidak melarang caching — ia memerlukan pemeriksaan salinan cache pada setiap penggunaan melalui permintaan bersyarat (If-Modified-Since atau If-None-Match). Jika server merespons 304 — klien menggunakan cache. Jika 200 — memperbarui. no-store sebaliknya melarang penyimpanan respons di cache apa pun, termasuk disk dan memori. Gunakan no-store hanya untuk data sensitif — token, data pembayaran, dokumen pribadi.

Cache-Control vs Expires

Header Expires (HTTP/1.0) juga menunjukkan waktu hidup sumber daya, tetapi menggunakan tanggal absolut: Expires: Thu, 03 Jul 2026 12:00:00 GMT. Cache-Control max-age — waktu relatif dari saat respons. Perbedaan ini kritis untuk sistem terdistribusi: jika server dan klien berada di zona waktu berbeda, Expires dapat ditafsirkan secara salah. Cache-Control tidak memiliki masalah ini — 3600 detik selalu 3600 detik.

Ketika kedua header hadir, Cache-Control memiliki prioritas di atas Expires. Ini ditetapkan dalam RFC 7234: “Jika respons berisi Cache-Control dengan direktif max-age, penerima HARUS mengabaikan Expires”. Dalam praktiknya, disarankan untuk tidak mengembalikan Expires untuk klien modern, karena Cache-Control mencakup semua skenario Expires. Namun, untuk kompatibilitas mundur dengan proxy dan browser lama, kedua header dapat dikembalikan.

Expires sebagian besar bertahan untuk konten statis di Nginx dan Apache — server ini secara otomatis menambahkan kedua header. Jika dalam proyek Anda Anda menemukan Expires tanpa Cache-Control, gantilah dengan Cache-Control dengan max-age: presisi manajemen cache meningkat dan ketergantungan pada zona waktu dihilangkan. Untuk migrasi, cukup konfigurasi server untuk menambahkan Cache-Control sebagai ganti Expires.

nginx
# Nginx: Cache-Control untuk file statis
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;
    add_header Cache-Control "public, immutable, max-age=2592000";
}

# Kebijakan berbeda untuk jenis konten yang berbeda
location /api/config {
    expires -1;
    add_header Cache-Control "no-cache, must-revalidate";
}

location /api/static-data {
    expires 5m;
    add_header Cache-Control "public, max-age=300";
}

Dalam konfigurasi Nginx untuk file statis (CSS, JS, gambar) Cache-Control diatur selama 30 hari dengan atribut immutable — atribut ini memberi tahu browser bahwa sumber daya tidak pernah berubah di bawah URL ini (penomoran versi melalui hash di nama file). Endpoint API menggunakan no-cache untuk data dinamis dan public dengan max-age pendek untuk data referensi — daftar yang sering diminta dan jarang berubah.

Caching dalam aplikasi seluler

Dalam aplikasi seluler, Cache-Control memainkan peran khusus karena keterbatasan jaringan seluler: latensi tinggi, koneksi tidak stabil, batas lalu lintas. Caching yang tepat memungkinkan pengguna melihat data secara instan, bahkan offline, dan memperbaruinya di latar belakang. OkHttp di Android dan URLSession di iOS memiliki sistem caching bawaan yang memperhitungkan Cache-Control.

OkHttp menggunakan CacheInterceptor yang membaca Cache-Control dari respons dan secara otomatis mengelola caching. Jika server mengembalikan Cache-Control: max-age=3600, OkHttp tidak akan mengirim permintaan ke server selama satu jam. Setelah max-age kedaluwarsa, OkHttp mengirim permintaan bersyarat dengan If-Modified-Since dan If-None-Match. Konfigurasi cache di OkHttp: OkHttpClient.Builder().cache(Cache(directory, maxSize)).

kotlin
fun createCachedClient(cacheDir: File): OkHttpClient {
    return OkHttpClient.Builder()
        .cache(Cache(cacheDir, 10L * 1024 * 1024))
        .addNetworkInterceptor { chain ->
            val response = chain.proceed(chain.request())
            response.newBuilder()
                .header("Cache-Control",
                    "public, max-age=300")
                .removeHeader("Pragma")
                .build()
        }
        .build()
}

Kode membuat OkHttpClient dengan cache 10 MB dan menggantikan Cache-Control melalui NetworkInterceptor. Jika server tidak mengembalikan Cache-Control atau menggunakan Expires, interceptor menambahkan public, max-age=300 (5 menit). Interceptor menghapus header Pragma usang (HTTP/1.0) untuk kompatibilitas. Dengan skema yang sama, caching di iOS bekerja melalui URLCache.shared dengan konfigurasi memoryCapacity dan diskCapacity.

Mode offline dan stale-while-revalidate

Direktif stale-while-revalidate memungkinkan pengguna melihat cache usang (stale) sementara aplikasi memuat data segar di latar belakang. Ini memberikan efek respons instan: pengguna melihat konten segera, dan setelah satu detik konten diperbarui. Didukung oleh OkHttp mulai versi 3.10 dan URLCache di iOS 14+. Contoh: Cache-Control: max-age=3600, stale-while-revalidate=300 — 1 jam cache aktif, lalu 5 menit tampilan cache usang dengan pembaruan latar belakang.

Contoh konfigurasi Cache-Control

Jenis sumber daya yang berbeda memerlukan strategi caching yang berbeda. Mari kita lihat konfigurasi optimal untuk skenario umum dalam pengembangan seluler. Untuk konten statis dengan hash di nama file (bundle.abc123.js) dapat mengatur max-age hingga 1 tahun dengan immutable. Untuk daftar API yang jarang diperbarui (katalog, kategori) — max-age dari 5 menit hingga 1 jam dengan stale-while-revalidate.

Jenis sumber dayaCache-ControlPenjelasan
Statis dengan versipublic, max-age=31536000, immutable1 tahun, file tidak berubah (hash di URL)
Statis tanpa versipublic, max-age=86400, must-revalidate1 hari dengan pemeriksaan wajib setelahnya
API: data referensipublic, max-age=600, stale-while-revalidate=6010 menit cache + 1 menit stale
API: data penggunaprivate, max-age=601 menit, hanya untuk pengguna tertentu
API: data sensitifno-storeLarang caching sepenuhnya
Halaman HTMLno-cache, must-revalidatePemeriksaan setiap permintaan, 304 jika tidak berubah

Penting untuk diingat tentang keamanan: untuk respons yang berisi data pribadi pengguna, selalu atur private. Tanpa direktif ini, proxy publik (misalnya perusahaan) dapat menyimpan respons dalam cache dan memberikannya kepada pengguna lain. Untuk token autentikasi dan informasi pembayaran, gunakan no-store — bahkan cache private tidak boleh menyimpan data ini ke disk.

Debugging caching

Untuk memeriksa kebenaran Cache-Control, gunakan header Age (berapa detik cache disimpan) dan X-Cache (hit/miss di CDN). Di browser — tab Network, kolom Size menunjukkan “from disk cache” atau “304 Not Modified”. Jika sumber daya harus di-cache tetapi dimuat setiap kali — periksa apakah server tidak menambahkan Cache-Control: no-cache atau Pragma: no-cache bersama dengan direktif Anda.

Pertanyaan yang Sering Diajukan

Apa perbedaan antara max-age dan s-maxage?

max-age berlaku untuk semua cache (termasuk browser), s-maxage — hanya untuk shared cache (proxy, CDN). Jika s-maxage ditentukan, CDN mengabaikan max-age dan menggunakan s-maxage. Ini memungkinkan pengaturan waktu hidup yang berbeda untuk browser dan CDN.

Bisakah caching dibatalkan setelah mengirim Cache-Control?

Tidak, setelah mengirim respons dengan max-age, klien tidak akan mengirim permintaan sampai timer kedaluwarsa. Untuk membatalkan cache segera, Anda perlu mengubah URL sumber daya (menambahkan versi/hash) dan mengirim notifikasi push atau pesan WebSocket untuk reset paksa.

Apa itu direktif immutable?

Direktif immutable (RFC 8246) memberi tahu browser bahwa sumber daya tidak akan pernah berubah di bawah URL ini. Browser bahkan tidak mencoba mengirim permintaan bersyarat saat menyegarkan halaman — menggunakan cache hingga max-age kedaluwarsa. Hanya berfungsi dengan file yang diberi versi.

Bagaimana Cache-Control memengaruhi SEO?

Googlebot memperhitungkan Cache-Control: caching lama mempercepat pemindaian ulang. noindex dengan cache cepat — ok. no-store dapat memperlambat pengindeksan, karena Googlebot akan memuat halaman dari awal setiap kali. max-age yang terlalu pendek meningkatkan beban server saat pemindaian.

Bagaimana cara mengkonfigurasi Cache-Control di Express.js?

Melalui helmet atau middleware: res.set('Cache-Control', 'public, max-age=3600'). Untuk statis, gunakan express.static dengan parameter maxAge: express.static('public', {maxAge: '1y'}). Untuk rute dinamis — secara individual di setiap handler.

Kesimpulan

  • Cache-Control — header HTTP utama untuk manajemen caching dengan sistem direktif yang fleksibel
  • max-age — waktu hidup dalam detik sejak respons; direktif kunci untuk semua skenario caching
  • private vs public — private hanya untuk klien, public untuk proxy dan CDN; memengaruhi keamanan data
  • no-cache memerlukan pemeriksaan, no-store melarang caching sepenuhnya; tujuan berbeda, jangan tertukar
  • s-maxage — menggantikan max-age untuk shared cache, berguna untuk memisahkan kebijakan browser/CDN
  • stale-while-revalidate — menampilkan cache usang dengan pembaruan latar belakang untuk UX instan
  • Rekomendasi — konfigurasikan Cache-Control untuk setiap jenis sumber daya di server dan di klien HTTP seluler

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga