Cache-Control — nedir, yönergeler ve önbellek yönetimi

Yazar: IT Sectr Yayınlanma: 2026-03-09 Okuma süresi: 9 dk

Cache-Control, bir dizi yönerge kullanarak kaynakların istemci, proxy sunucular ve CDN taraflarında önbelleğe alınma kurallarını tanımlayan bir HTTP başlığıdır. Kullanımdan kaldırılan Expires başlığının aksine, Cache-Control düzinelerce kombinasyonu destekler: max-age saniye cinsinden ömrü belirler, private ve public önbellek kullanılabilirliğini kontrol eder, no-cache ve no-store — zorunlu doğrulama. Google Web Dev (2025)'e göre, doğru Cache-Control yapılandırması, tekrarlanan ziyaretlerde sayfa yükleme sürelerini %50-80 oranında azaltabilir. Bu, başlığı web ve mobil uygulama performansı için kritik hale getiriyor.

Ana Noktalar

  • Cache-Control — istemci, proxy ve CDN'de önbelleği kontrol eden yönergeleri olan bir HTTP başlığı
  • max-age — yeniden doğrulama olmadan kaynağın ömrünü saniye cinsinden belirleyen ana yönerge
  • private vs public — private yalnızca istemcide önbelleğe izin verir, public proxy ve CDN'lerde de izin verir
  • no-cache vs no-store — no-cache kullanımdan önce doğrulama gerektirir, no-store önbelleği tamamen yasaklar
  • s-maxage — tarayıcıları etkilemeden paylaşılan önbellekler için max-age'i geçersiz kılar

Cache-Control Nedir?

Cache-Control, HTTP/1.1'de (RFC 7234) standartlaştırılmış bir HTTP başlığıdır ve sunucunun, istemcilerin, proxy'lerin ve CDN'lerin yanıtı nasıl ve ne kadar süreyle önbelleğe alabileceğini belirtmesine olanak tanır. Expires'ten (HTTP/1.0) farklı olarak, Cache-Control yönergeleri kullanır — virgülle birleştirilmiş metin komutları: Cache-Control: public, max-age=3600, must-revalidate. Başlık, önbellek zincirindeki her halka üzerinde ince ayarlı kontrol sağlar.

Önbellek, web ve mobil uygulama performansının temel mekanizmalarından biridir. Olmadan, her kullanıcı isteği doğrudan sunucuya gider ve aşırı yük ve gecikmeye neden olur. Cache-Control üç önbellek düzeyi tanımlar: tarayıcı/uygulama (özel önbellek), proxy sunucular (paylaşılan önbellek) ve CDN (dağıtık önbellek). Her düzey yönergeleri farklı yorumlar.

Yanlış Cache-Control yapılandırması, performans sorunlarının en yaygın nedenlerinden biridir. Çok agresif önbellek, kullanıcıların eski verileri görmesine neden olur. Çok zayıf önbellek, sunucuya aşırı istek ve yavaş yüklemeye yol açar. Akamai (2025)'e göre, statik içerik için Cache-Control'u optimize etmek, sunucu yükünü %70-90 azaltır ve mobil kullanıcılar için yükleme süresini %40-60 iyileştirir.

Başlığın Tarihçesi

Cache-Control, HTTP/1.1'de (RFC 2616, 1999) Expires'in yerine geçmek üzere ortaya çıktı. Expires'in temel bir sorunu vardı: sunucu ve istemci saat dilimlerine bağlı olan mutlak bir tarih kullanıyordu. Cache-Control, göreceli zamana (yanıtın alındığı andan itibaren saniye cinsinden max-age) geçerek bu sorunu çözdü. Daha sonra, RFC 7234'te (2014) yeni yönergeler eklendi: statik varlıklar için immutable, gecikmeli doğrulama için stale-while-revalidate ve stale-if-error.

Cache-Control Yönergeleri

Cache-Control, üç gruba ayrılmış 10'dan fazla yönerge içerir: istek yönergeleri (istemci → sunucu), yanıt yönergeleri (sunucu → istemci) ve uzantılar. Pratikte, mobil geliştirme, önbellek senaryolarının %95'ini kapsayan 6-7 ana yanıt yönergesi kullanır. Her birini örnekler ve önerilerle inceleyelim.

YönergeAnlamıÖrnek
max-ageYanıt anından itibaren saniye cinsinden ömürmax-age=3600 — 1 saat
s-maxagePaylaşılan önbellek için max-age (proxy, CDN)s-maxage=86400 — CDN için 1 gün
publicHerkesin önbelleğe almasına izin verir (proxy'ler dahil)public, max-age=3600
privateYalnızca tarayıcı/uygulama için önbelleğe izin verirprivate, max-age=600
no-cacheDoğrulama olmadan kullanma (304 gerekli)no-cache
no-storeÖnbelleği tamamen yasaklano-store
must-revalidatemax-age'den sonra kaynakla yeniden doğrulama yapılmalımax-age=3600, must-revalidate
immutableKaynak değişmeyecek (sürüm numarası verilmiş statik varlıklar için)max-age=31536000, immutable

max-age en önemli yönergedir. İstemcinin belirtilen süre boyunca sunucuya istek göndermesini yasaklar. Statik varlıklar (CSS, JS, görseller) için max-age genellikle 1 gün ila 1 yıl arasında ayarlanır. API yanıtları için — 0 saniye (her zaman güncel veri) ila 5-10 dakika (referans verileri) arasındadır. s-maxage, CDN ve tarayıcı için farklı ömürler ayarlamaya olanak tanır: CDN 1 gün boyunca bir kopya saklar, tarayıcı 1 saat boyunca saklar.

no-cache vs no-store

Bu iki yönerge sıklıkla karıştırılır. no-cache önbelleği yasaklamaz — koşullu bir istek (If-Modified-Since veya If-None-Match) aracılığıyla her kullanımda önbelleğe alınmış kopyayı doğrulamayı gerektirir. Sunucu 304 ile yanıt verirse — istemci önbelleği kullanır. 200 ise — günceller. no-store ise, disk ve bellek dahil olmak üzere herhangi bir önbellekte yanıtı kaydetmeyi tamamen yasaklar. no-store'u yalnızca hassas veriler için kullanın — token'lar, ödeme verileri, kişisel belgeler.

Cache-Control ve Expires

Expires başlığı (HTTP/1.0) da kaynağın ömrünü belirtir ancak mutlak bir tarih kullanır: Expires: Thu, 03 Jul 2026 12:00:00 GMT. Cache-Control max-age, yanıt anından itibaren göreceli süreyi kullanır. Fark, dağıtık sistemler için kritiktir: sunucu ve istemci farklı saat dilimlerindeyse Expires yanlış yorumlanabilir. Cache-Control'de bu sorun yoktur — 3600 saniye her zaman 3600 saniyedir.

Her iki başlık da mevcut olduğunda, Cache-Control Expires'a göre önceliklidir. Bu, RFC 7234'te tanımlanmıştır: “Bir yanıt, max-age yönergesiyle bir Cache-Control alanı içeriyorsa, alıcı Expires alanını GÖRMEZDEN GELMELİDİR.” Pratikte, modern istemciler için Expires'ın hiç döndürülmemesi önerilir, çünkü Cache-Control tüm Expires senaryolarını kapsar. Ancak, eski proxy'ler ve tarayıcılarla geriye dönük uyumluluk için her iki başlık da döndürülebilir.

Expires, esas olarak Nginx ve Apache'deki statik içerik için varlığını sürdürmektedir — bu sunucular otomatik olarak her iki başlığı da ekler. Projeniz Cache-Control olmadan Expires ile karşılaşırsa, onu max-age ile Cache-Control ile değiştirin: önbellek kontrolü doğruluğu artar ve saat dilimine bağımlılık ortadan kalkar. Geçiş için, sunucuyu Expires yerine Cache-Control ekleyecek şekilde yapılandırmak yeterlidir.

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

# Farklı içerik türleri için farklı politikalar
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";
}

Nginx yapılandırmasında, statik dosyalar (CSS, JS, görseller) immutable özelliğiyle 30 gün boyunca Cache-Control olarak ayarlanır — bu özellik, tarayıcıya kaynağın bu URL'de asla değişmeyeceğini bildirir (dosya adındaki hash aracılığıyla sürümleme). API uç noktaları, dinamik veriler için no-cache ve referans verileri için kısa max-age ile public kullanır — sıkça talep edilen ve nadiren değişen listeler.

Mobil Uygulamalarda Önbellek

Mobil uygulamalarda Cache-Control, mobil ağların sınırlamaları nedeniyle özel bir rol oynar: yüksek gecikme, dengesiz bağlantı, trafik limitleri. Doğru önbellek, kullanıcıya verileri anında göstermeye, hatta çevrimdışıyken bile göstermeye ve arka planda güncellemeye olanak tanır. Android'de OkHttp ve iOS'ta URLSession, Cache-Control'a saygı duyan yerleşik önbellek sistemlerine sahiptir.

OkHttp, yanıttan Cache-Control'u okuyan ve önbelleği otomatik olarak yöneten CacheInterceptor'u kullanır. Sunucu Cache-Control: max-age=3600 döndürdüyse, OkHttp bir saat boyunca sunucuya istek göndermez. max-age süresi dolduktan sonra OkHttp, If-Modified-Since ve If-None-Match ile koşullu bir istek gönderir. OkHttp'de önbellek yapılandırması: 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()
}

Kod, 10 MB önbelleğe sahip bir OkHttpClient oluşturur ve NetworkInterceptor aracılığıyla Cache-Control'u geçersiz kılar. Sunucu Cache-Control döndürmez veya Expires kullanırsa, interceptor public, max-age=300 (5 dakika) ekler. Interceptor, uyumluluk için kullanımdan kaldırılan Pragma başlığını (HTTP/1.0) kaldırır. iOS'ta önbellek, memoryCapacity ve diskCapacity ayarlarıyla URLCache.shared aracılığıyla benzer şekilde çalışır.

Çevrimdışı Mod ve stale-while-revalidate

stale-while-revalidate yönergesi, uygulama arka planda yeni verileri alırken kullanıcıya eski önbelleği göstermeye olanak tanır. Bu, anında yanıt efekti sağlar: kullanıcı içeriği hemen görür ve bir saniye sonra güncel sürüme güncellenir. OkHttp sürüm 3.10'dan itibaren ve iOS 14+'ta URLCache tarafından desteklenir. Örnek: Cache-Control: max-age=3600, stale-while-revalidate=300 — 1 saat güncel önbellek, ardından arka planda güncellemeyle 5 dakika eski veri gösterimi.

Cache-Control Yapılandırma Örnekleri

Farklı kaynak türleri farklı önbellek stratejileri gerektirir. Mobil geliştirmedeki tipik senaryolar için en uygun yapılandırmaları inceleyelim. Dosya adında hash olan statik içerik (bundle.abc123.js) için, immutable ile max-age'i 1 yıla kadar ayarlayabilirsiniz. Nadiren güncellenen API listeleri (dizinler, kategoriler) için — stale-while-revalidate ile 5 dakikadan 1 saate kadar max-age.

Kaynak TürüCache-ControlAçıklama
Sürüm numarası verilmiş statik varlıklarpublic, max-age=31536000, immutable1 yıl, dosyalar değişmez (URL'de hash)
Sürüm numarası verilmemiş statik varlıklarpublic, max-age=86400, must-revalidateSonrasında zorunlu yeniden doğrulama ile 1 gün
API: referans verileripublic, max-age=600, stale-while-revalidate=6010 dakika önbellek + 1 dakika eski
API: kullanıcı verileriprivate, max-age=601 dakika, yalnızca belirli bir kullanıcı için
API: hassas verilerno-storeTam önbellek yasağı
HTML sayfalarıno-cache, must-revalidateHer istekte doğrulama, değişiklik yoksa 304

Güvenliği hatırlamak önemlidir: kullanıcının kişisel verilerini içeren yanıtlar için her zaman private ayarlayın. Bu yönerge olmadan, genel bir proxy (örneğin, kurumsal) yanıtı önbelleğe alabilir ve başka bir kullanıcıya iletebilir. Kimlik doğrulama token'ları ve ödeme bilgileri için no-store kullanın — özel bir önbellek bile bu verileri diskte saklamamalıdır.

Önbellek Hata Ayıklama

Cache-Control'un doğruluğunu doğrulamak için Age başlığını (önbelleğin kaç saniye saklandığı) ve X-Cache'i (CDN'de hit/miss) kullanın. Tarayıcıda — Network sekmesi, Size sütunu “from disk cache” veya “304 Not Modified” gösterir. Bir kaynağın önbelleğe alınması gerekirken her seferinde yükleniyorsa, sunucunun yönergelerinizle birlikte Cache-Control: no-cache veya Pragma: no-cache ekleyip eklemediğini kontrol edin.

Sıkça Sorulan Sorular

max-age ve s-maxage arasındaki fark nedir?

max-age tüm önbellekler için geçerlidir (tarayıcılar dahil), s-maxage yalnızca paylaşılan önbellekler (proxy, CDN) için geçerlidir. s-maxage belirtilmişse, CDN max-age'i yok sayar ve s-maxage kullanır. Bu, tarayıcı ve CDN için farklı ömürler ayarlamaya olanak tanır.

Cache-Control gönderdikten sonra önbellek iptal edilebilir mi?

Hayır, max-age ile bir yanıt gönderdikten sonra, zamanlayıcı süresi dolana kadar istemci istek göndermez. Anında önbellek geçersiz kılma için, kaynak URL'sini değiştirmeniz (sürüm/hash ekleme) ve zorunlu sıfırlama için push bildirimleri veya WebSocket mesajları göndermeniz gerekir.

immutable yönergesi nedir?

immutable yönergesi (RFC 8246), tarayıcıya kaynağın bu URL'de asla değişmeyeceğini bildirir. Tarayıcı, sayfayı yenilerken koşullu bir istek göndermeye bile çalışmaz — max-age süresi dolana kadar önbelleği kullanır. Yalnızca sürüm numarası verilmiş dosyalarla çalışır.

Cache-Control SEO'yu nasıl etkiler?

Googlebot Cache-Control'u dikkate alır: uzun önbellek, tekrarlanan taramayı hızlandırır. Hızlı önbellek ile noindex sorun değildir. no-store, indekslemeyi yavaşlatabilir çünkü Googlebot sayfayı her seferinde sıfırdan yükler. Çok kısa max-age, tarama sırasında sunucu yükünü artırır.

Express.js'de Cache-Control nasıl yapılandırılır?

helmet veya middleware aracılığıyla: res.set('Cache-Control', 'public, max-age=3600'). Statik dosyalar için, maxAge parametresiyle express.static kullanın: express.static('public', {maxAge: '1y'}). Dinamik rotalar için — her işleyicide ayrı ayrı.

Özet

  • Cache-Control — esnek yönerge sistemiyle önbellek yönetimi için ana HTTP başlığı
  • max-age — yanıt anından itibaren saniye cinsinden ömür; tüm önbellek senaryoları için ana yönerge
  • private vs public — private yalnızca istemci için, public proxy ve CDN için; veri güvenliğini etkiler
  • no-cache doğrulama gerektirir, no-store önbelleği tamamen yasaklar; amaçlar farklı, karıştırmayın
  • s-maxage — paylaşılan önbellekler için max-age'i geçersiz kılar, tarayıcı/CDN politikalarını ayırmak için kullanışlı
  • stale-while-revalidate — anlık UX için arka planda güncellemeyle eski önbellek gösterimi
  • Öneri — sunucuda ve mobil HTTP istemcisinde her kaynak türü için Cache-Control yapılandırın

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun