Cache ve Performans

Cache Miss ve Cache Hit Nedir?

Cache hit ve cache miss istek akışlarını karşılaştıran; kısa hit yolu ile uzun miss yolunu gösteren teknik diyagram

İki kullanıcı aynı sayfayı açıyor. Biri 70 ms'de yanıt alıyor; diğeri 550 ms bekliyor. Aynı sunucu, aynı içerik, farklı sonuç. Fark büyük olasılıkla tek bir kavramda gizli: cache hit mi yoksa cache miss mi yaşandı.

Cache'e gelen her istek iki sonuçla karşılaşır. İstenen kaynak orada ve hâlâ geçerliyse doğrudan teslim edilir — bu bir hit'tir. Kaynak yoksa ya da süresi dolmuşsa origin sunucuya gidilmek zorunda kalınır — bu bir miss'tir. Aralarındaki performans farkı basit bir gecikme meselesi değildir. Miss, bağlantı kurma, protokol el sıkışması ve sunucu işlem süresiyle birlikte gelen tam bir yük zinciridir.

Hit oranı ne kadar yüksekse origin'e düşen yük o kadar azdır, kullanıcıların aldığı yanıtlar o kadar hızlıdır. Bu oran artırılabilir bir değişkendir; ama neyin onu düşürdüğünü anlamadan artırma girişimi doğru noktaya basmaz.

Hit ve miss arasındaki temel ayrım

Cache hit, isteğin cache katmanında karşılanması demektir. Tarayıcı, CDN düğümü ya da reverse proxy — hangi katmanda olursa olsun — kaynak geçerli biçimde orada duruyorsa istek origin'e hiç ulaşmaz. Yanıt anında döner. Gecikme yalnızca cache katmanı ile kullanıcı arasındaki ağ mesafesiyle sınırlıdır.

Cache miss ise tam tersine, cache'in isteği karşılayamaması durumudur. Kaynak hiç cache'lenmemiş olabilir, süresi dolmuş olabilir ya da önbellek temizlenmiş olabilir. Her üç durumda da istek origin'e iletilir. Origin yanıt üretir, yanıt cache'e yazılır ve kullanıcıya iletilir. Kullanıcı bu sürecin tamamını bekler. İki sonuç arasındaki fark, pratik olarak yüzlerce milisaniyeye ulaşabilir.

Hit oranının performansa doğrudan katkısı

Hit oranı, toplam istek sayısı içinde cache'ten yanıtlanan isteklerin yüzdesidir. %95 hit oranı, 100 isteğin 95'inin origin'e ulaşmadan döndürüldüğü anlamına gelir. Bu oran arttıkça iki şey aynı anda iyileşir: kullanıcıların aldığı yanıt hızı ve origin sunucu üzerindeki yük.

CDN'lerin hız üzerindeki etkisi büyük ölçüde bu orana bağlıdır. Yüksek hit oranı olan bir CDN düğümü, kullanıcıya coğrafi olarak yakın bir konumdan saniyeler içinde yanıt verebilir. Hit oranı düşükse CDN varlığının faydası sınırlı kalır: her miss yeniden origin'e gidip geliyor, mesafenin avantajı kullanılamıyor. Hit oranını takip etmek, cache stratejisinin gerçekten çalışıp çalışmadığını göstermek için en temel göstergedir.

Cold cache: ilk ziyaretin maliyeti

Cache boşken — yeni bir CDN düğümü devreye girdiğinde, deploy sonrasında veya önbellek temizlendikten hemen sonra — gelen tüm istekler zorunlu olarak miss yaşar. Bu durum cold cache olarak adlandırılır. Cache dolmaya başlayana kadar her istek origin'e gider; bu dönemde hit oranı sıfıra yakındır.

Cold cache'in maliyeti büyük trafik hacimlerinde özellikle belirginleşir. Yeni bir içerik yayınlandığında ya da cache temizlendiğinde ani trafik artışları origin sunucuyu beklenmedik biçimde zorlayabilir. Aynı kaynak için çok sayıda eş zamanlı miss birlikte geldiğinde "thundering herd" olarak bilinen bu durum, origin'e aniden çok sayıda istek düşmesiyle sonuçlanır. Bunun önüne geçmek için cache warming uygulanır — sıradaki bölümde bu mekanizma ele alınacak.

Warm cache: tekrar eden istekte neler değişir

Cache dolduğunda, yani warm cache aşamasına geçildiğinde, aynı kaynakları isteyen sonraki kullanıcılar hit deneyimi yaşar. Origin ile bağlantı kurulmaz, bant genişliği ve işlem süresi harcanmaz. Kullanıcı, kaynağın cache'te ne kadar süredir durduğundan habersizdir — aldığı yanıt aynı hızdadır.

Warm cache, tekrarlayan trafiğin yoğun olduğu sitelerde çok daha belirgin performans avantajı yaratır. Aynı içeriğin binlerce kez isteneceği bir haber sitesinde veya popüler bir ürün sayfasında cache'in ısınması hızlıdır; hit oranı yüksek tutulabilir. Düşük trafikli ya da kişiselleştirilmiş içerik ağırlıklı sitelerde ise cache'i ısıtmak daha güçtür ve hit oranı doğal olarak daha düşük kalır.

Cache miss maliyetinin katmanları

Bir miss gerçekleştiğinde, origin ile henüz aktif bir bağlantı yoksa işlem birkaç adımda ilerler. Önce DNS çözümlemesi yapılır: alan adı IP adresine dönüştürülür. Ardından TCP bağlantısı kurulur. HTTPS kullanılıyorsa TLS el sıkışması eklenir. Tüm bu adımlar tamamlandıktan sonra asıl istek origin'e iletilir ve origin'in yanıt üretmesi beklenir.

Bu zincirin toplam süresi, kullanıcının coğrafi konumuna, origin sunucunun yanıt hızına ve ağ kalitesine bağlı olarak değişir. Pratikte bu gecikme 200–800 ms arasında bir yere oturabilir; iyi koşullarda daha az, zayıf bağlantılarda daha fazla. TTFB değerini incelerken cache miss'in bu zinciri tetiklediğini akılda tutmak gerekir. Origin yanıtı ne kadar hızlı olursa olsun, bağlantı kurma adımları devre dışı bırakılamaz.

Stale-while-revalidate mekanizması

Cache'teki bir kaynak TTL'ini doldurduğunda iki seçenek vardır. Klasik yaklaşımda istek engellenir, origin'den yeni yanıt beklenir, ardından kullanıcıya iletilir. Bu süre zarfında kullanıcı bekler. Alternatif yaklaşım olan stale-while-revalidate ise farklı çalışır: süresi dolmuş kaynak anında döndürülür, arka planda origin'den yenisi alınır ve cache güncellenir.

Kullanıcı bu mekanizma sayesinde gecikme yaşamaz. Aldığı içerik birkaç saniyelik ya da birkaç dakikalık bir gecikmesiyle "eski" olabilir, ama büyük çoğunluk için bu kabul edilebilir bir trade-off'tur. Cache-Control: max-age=300, stale-while-revalidate=60 gibi bir direktifle 300 saniyelik TTL dolduğunda ek 60 saniyelik bir pencerede eski içerik sunulmaya devam eder ve bu süre içinde arka planda güncelleme gerçekleşir. Sık değişen ama anlık doğruluk zorunluluğu olmayan içerikler için bu yöntem güçlü bir seçenektir.

Shared cache ve private cache ayrımı

Her cache katmanı aynı kapsamda çalışmaz. Tarayıcı cache'i private'tır — yalnızca o tarayıcının yaptığı istekleri saklar. Bir kullanıcı bir sayfayı ziyaret ettiğinde tarayıcısına yazılan cache, başka bir kullanıcıya hizmet edemez. Bunun karşısında CDN ve reverse proxy cache'leri shared'dır: binlerce farklı kullanıcının isteğine aynı cache'ten yanıt verilebilir.

Edge cache, shared cache'in coğrafi olarak dağıtılmış biçimidir. Bir kullanıcının isteği düğümde miss yaratıp origin'den çekildikten sonra cache'e yazılır; ardından aynı düğümden gelen farklı kullanıcıların istekleri hit olarak yanıtlanır. Cache-Control direktiflerinde private belirtilirse kaynak yalnızca tarayıcıda cache'lenir, CDN bu kaynağı saklayamaz. Kullanıcıya özel içerik için bu doğru seçimdir; ama genel içeriklerde private kullanmak shared cache'in tüm avantajını ortadan kaldırır.

Cache key: hit oranını belirleyen yapı

Her cache girişi bir anahtarla (key) tanımlanır. Çoğu durumda bu anahtar URL'dir. Ancak aynı URL farklı query parametreleriyle geliyorsa her kombinasyon ayrı bir cache girişi oluşturabilir. /urun?renk=kirmizi ile /urun?renk=mavi&sirala=fiyat aynı sayfayı döndürdüğü halde cache'te farklı keyler olarak tutulursa her biri ayrı ayrı miss yaratır.

Gereksiz query parametreleri cache'i parçalar ve hit oranını düşürür. CDN'lerin büyük bölümü hangi parametrelerin cache key'e dahil edileceğini yapılandırma yoluyla belirlemeye izin verir. Analytics parametreleri (utm_source, fbclid gibi) içeriği değiştirmez; bu parametreleri cache key dışında bırakmak, aynı içerik için hit oranını ciddi biçimde artırabilir.

Vary header ve cache parçalanması

Vary başlığı, aynı URL için birden fazla cache versiyonu tutulmasını sağlar. Vary: Accept-Encoding eklendiğinde gzip ve brotli ile sıkıştırılmış yanıtlar ayrı ayrı cache'lenir; tarayıcı hangi formatı destekliyorsa ona uygun versiyon döner. Bu, sıkıştırma desteği değişen istemciler arasında doğru içeriği sunmak için gereklidir.

Ama Vary dikkatli kullanılmazsa cache'i aşırı parçalayabilir. Vary: User-Agent gibi bir direktif, her farklı kullanıcı ajanı için ayrı bir cache girişi oluşturur; bu durumda hit oranı dramatik biçimde düşer. Vary'yi yalnızca gerçekten farklı yanıt üretilen boyutlar için kullanmak, cache verimliliğini korur. İçerik değişmiyorsa Vary'ye gerek yoktur; eklendiğinde ise cache'in ne kadar parçalandığı düzenli olarak kontrol edilmeli.

TTL kararı ve hit oranı ilişkisi

TTL (Time to Live), bir cache girişinin ne kadar süre geçerli sayılacağını belirler. Cache-Control başlıklarıyla tanımlanan bu değer, hit oranını doğrudan etkiler. Çok kısa TTL — örneğin 60 saniye — sık miss anlamına gelir. Her dakikada bir istek origin'e gidebilir. Çok uzun TTL — günler veya haftalar — yüksek hit oranı sağlar ama içerik değiştiğinde kullanıcılar eski versiyonu görmeye devam eder.

İdeal TTL, içeriğin ne sıklıkla değiştiğiyle doğru orantılı olarak belirlenir. Sürümlü statik dosyalar — yani dosya adında hash bulunanlar — değiştiğinde zaten yeni bir URL alır; bu nedenle çok uzun TTL güvenle kullanılabilir. Oysa sık güncellenen HTML sayfaları için kısa TTL veya stale-while-revalidate kombinasyonu daha mantıklıdır. Her kaynak tipi için tek bir TTL uygulamak yerine kaynak kategorisine göre farklı değerler belirlemek hem hız hem doğruluk açısından avantaj sağlar.

Cache warming stratejileri

Deploy sonrasında cache sıfırlanır ve cold cache dönemi başlar. Bu dönemde gelen gerçek kullanıcı istekleri miss yaşar; trafik yoğunsa origin aniden ağır bir yük altına girebilir. Cache warming, deploy ardından kritik URL'leri önceden çekerek cache'i doldurmayı hedefler.

Uygulama yöntemi basittir: deploy tamamlandıktan sonra en sık ziyaret edilen sayfaların URL'leri otomatik olarak bir araç tarafından istenir. Bu istekler miss yaratır, yanıtlar cache'e yazılır. Gerçek kullanıcılar geldiğinde cache zaten dolmuştur. Büyük sitelerde tüm URL'leri önceden çekmek mümkün değildir; bu durumda öncelik en yüksek trafikli sayfalara verilir. CDN sağlayıcılarının bir bölümü bu süreci otomatikleştiren araçlar sunar ya da deploy pipeline'ına entegre edilebilecek betikler gerektirir.

Hit oranını artırmaya yönelik pratik kararlar

Cache key normalizasyonu en hızlı kazanım noktalarından biridir. Analytics kampanya parametreleri (utm_source, gclid, fbclid) içeriği değiştirmez; bunları cache key'den çıkarmak, aynı sayfaya farklı kaynaklardan gelen isteklerin aynı cache girişini paylaşmasını sağlar. Bunu CDN yapılandırmasında "query string ignore" veya "cache key normalization" olarak adlandırılan seçeneklerle uygulamak mümkündür.

Statik varlıklar — CSS, JavaScript, görsel dosyaları — için dosya adına hash eklemek ve Cache-Control: immutable, max-age=31536000 kombinasyonu kullanmak hem çok yüksek hit oranı hem de içerik doğruluğu garantisi sağlar. Dosya değiştiğinde URL değişir, yeni bir cache girişi oluşur. Eski URL'ye gelen istekler hâlâ hit alır çünkü o versiyon hâlâ geçerlidir. Vary başlığını gereksiz boyutlara uygulamaktan kaçınmak, private direktifini yalnızca gerçekten kişisel içerikler için kullanmak ve TTL değerlerini içerik tipine göre farklılaştırmak bu temel kararları tamamlar.

Hit oranı nasıl ölçülür

CDN sağlayıcılarının büyük bölümü hit oranını doğrudan dashboard'da gösterir. Ek olarak her yanıtta dönen X-Cache veya CF-Cache-Status gibi response header'ları, o isteğin hit mi miss mi olduğunu tek tek söyler. Chrome DevTools'ta Network sekmesi açıkken bu header'lar incelenebilir; birden fazla istek üzerinde örüntü gözlemlenebilir.

Sunucu log'ları da aynı bilgiyi barındırır. Nginx ve Apache log formatına cache durumu eklenerek hangi kaynakların sürekli miss ürettiği tespit edilebilir. Sürekli miss üreten bir kaynak varsa nedeni araştırılmaya değer: TTL çok kısa mı ayarlanmış, cache key gereksiz biçimde parçalanmış mı, yoksa kaynak private olarak işaretlenmiş mi? Bu soruların yanıtı genellikle hit oranını artırmak için yapılacak değişikliğin tam olarak nerede olduğunu gösterir.

Cache hit ve cache miss, web performansının en temel ikili karşıtlıklarından biridir. Hit oranı ne kadar yüksekse kullanıcılar o kadar hızlı yanıt alır, origin o kadar az yorulur ve maliyet o kadar düşer. Ama bu oranı artırmak rastgele bir ayar değişikliğiyle olmaz — cache key yapısını, TTL değerlerini, Vary başlığı kullanımını ve içerik tipini birlikte değerlendirmek gerekir.

Miss'in kaçınılmaz olduğu durumlar da vardır: ilk ziyaretler, deploy sonrası cold cache dönemi, kişiselleştirilmiş içerik. Buradaki hedef sıfır miss değil, gereksiz miss'leri elimine etmek ve zorunlu miss'lerin maliyetini mümkün olduğunca azaltmaktır. Stale-while-revalidate gibi mekanizmalar bu maliyeti kullanıcıdan gizler; cache warming ise cold dönemin etkisini kısaltır.

Hit oranı bir anlık ölçüm değil, sürekli takip edilmesi gereken bir sağlık göstergesidir. Yeni içerik türleri eklendiğinde, CDN yapılandırması değiştiğinde ya da trafik örüntüsü farklılaştığında oran yeniden incelenmeli, gerekirse öncelikli URL'lerin cache davranışı gözden geçirilmeli.