Site Hızı & Performans

    Sunucu Tarafı Önbellekleme Katmanları

    OPcache'ten ters vekile kadar sunucu tarafı önbellek katmanlarının görev dağılımı ve kurulum mantığı.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Sunucu tarafı önbellekleme, sitenizin aynı işi ikinci kez yapmasını engelleme sanatıdır. Bir ziyaretçi ana sayfanızı açtığında PHP dosyaları derlenir, veritabanına on beş sorgu gider, şablon motoru HTML üretir ve sonuç tarayıcıya gönderilir. Bir sonraki ziyaretçi de aynı sayfayı isteyince bu zincirin tamamı baştan çalışır. Oysa üretilen sonuç değişmemiştir. Önbellekleme katmanları tam olarak bu tekrarı keser ve tipik bir WordPress kurulumunda 800 ms'lik bir yanıt süresini 40 ms'ye indirebilir.

    Bu rehberde önbelleği tek bir düğme gibi değil, üst üste binmiş katmanlar olarak ele alacağım: bytecode önbelleği (OPcache), nesne önbelleği (Redis/Memcached), tam sayfa önbelleği, ters vekil ve mikro önbellek, son olarak da tarayıcı ile CDN katmanı. Her katmanın neyi sakladığını, hangi problemi çözdüğünü ve yanlış kurulduğunda hangi tuhaf hataları ürettiğini gerçek yapılandırma örnekleriyle göstereceğim. Amaç, "hangi eklentiyi kurayım" sorusunun ötesine geçip isteğin sunucunuzda hangi duraklardan geçtiğini görmeniz.

    Önbellek Katmanları Haritası: İstek Nereden Geçer#

    Bir HTTP isteğinin sunucunuzda izlediği yolu tek bir hat gibi düşünün. İstek önce tarayıcının kendi önbelleğine takılır, oradan geçerse CDN kenar sunucusuna, oradan geçerse sizin ters vekilinize (Nginx/Varnish), oradan uygulama sunucusuna (PHP-FPM), oradan da veritabanına ulaşır. Her durak bir fırsattır: istek ne kadar erken bir katmanda cevaplanırsa maliyeti o kadar düşer. En pahalı yanıt, zinciri sonuna kadar kat eden yanıttır.

    Aşağıdaki tablo katmanları, ne sakladıklarını ve tipik kazancı özetliyor. Bu tabloyu bir kez oturttuğunuzda "sitem yavaş" şikâyetinde hangi katmana bakacağınızı bilirsiniz.

    KatmanNe saklarNerede çalışırTipik kazanç
    OPcacheDerlenmiş PHP bytecodePHP süreç belleği%30-70 CPU
    Nesne önbelleğiSorgu sonuçları, ara veriRedis / MemcachedVeritabanı yükünde büyük düşüş
    Tam sayfa önbelleğiÜretilmiş HTMLDisk / bellek / Nginx10-20 kat yanıt süresi
    Ters vekil / mikro önbellekKısa ömürlü HTMLNginx / VarnishTrafik zirvelerinde koruma
    CDN kenar önbelleğiStatik ve bazen HTMLKenar POP'larCoğrafi gecikme
    Tarayıcı önbelleğiCSS, JS, görselKullanıcı diskiTekrar ziyaret maliyeti sıfır

    Katmanların birbirini dışlamadığını fark edin; hepsi aynı anda açık olabilir ve olmalıdır. Bir yanlış anlama şudur: "Tam sayfa önbelleğim var, OPcache'e gerek yok." Oysa tam sayfa önbelleği yalnızca önbelleklenebilir sayfaları korur; sepet, ödeme, yönetim paneli ve giriş yapmış kullanıcı istekleri her zaman PHP'ye ulaşır ve orada OPcache devreye girer.

    OPcache: PHP'nin Derleme Maliyetini Sıfırlamak#

    PHP yorumlanan bir dildir ama her istekte kaynak kodu doğrudan çalıştırmaz; önce onu bytecode'a derler. OPcache bu derlenmiş bytecode'u paylaşılan bellekte tutar, böylece ikinci istekte derleme adımı tamamen atlanır. PHP 5.5'ten beri çekirdekte gelir ve bugün kapalı bırakılması için makul bir sebep yoktur. Etkinliğini kontrol etmek için:

    # OPcache yüklü ve açık mı
    php -i | grep -E "opcache.enable|opcache.memory_consumption|opcache.jit"
    
    # Çalışan FPM sürecinde gerçek durum (fpm ini'si CLI'dan farklı olabilir)
    php -r 'print_r(opcache_get_status(false)["memory_usage"]);'
    

    Tipik bir üretim yapılandırması /etc/php/8.3/fpm/conf.d/10-opcache.ini dosyasında şöyle görünür:

    opcache.enable=1
    opcache.memory_consumption=256      ; MB cinsinden; büyük projede 256-512
    opcache.interned_strings_buffer=16  ; tekrar eden string'ler için ayrı havuz
    opcache.max_accelerated_files=20000 ; dosya sayınızdan büyük olmalı
    opcache.revalidate_freq=60          ; kaç saniyede bir dosya mtime kontrolü
    opcache.validate_timestamps=1       ; üretimde 0 yaparsanız deploy'da reload şart
    opcache.save_comments=1             ; annotation kullanan framework'ler için gerekli
    

    Buradaki iki ayar sık sık başa bela olur. Birincisi opcache.max_accelerated_files: proje dosya sayınız bu değeri aşarsa OPcache fazlalıkları önbelleğe almaz ve hiçbir uyarı vermez; sitenin yarısı hızlı, yarısı yavaş olur. Dosya sayınızı find . -name "*.php" | wc -l ile ölçüp üstüne pay bırakın. İkincisi opcache.validate_timestamps=0: en yüksek performansı verir ama PHP artık dosya değişikliklerini fark etmez, yani her dağıtımdan sonra systemctl reload php8.3-fpm çalıştırmanız zorunludur. Bunu unutan ekipler "kodu değiştirdim ama site eski hâlini gösteriyor" diye saatlerce hata arar.

    Nesne Önbelleği: Redis ve Memcached#

    Nesne önbelleği, uygulamanızın hesapladığı ara sonuçları anahtar-değer biçiminde bellekte tutar. WordPress'te bir kategori sorgusunun sonucu, Laravel'de bir konfigürasyon dizisi, özel bir uygulamada bir API yanıtı bu katmana girer. Amaç veritabanına giden sorgu sayısını düşürmektir; iyi kurulmuş bir nesne önbelleği tipik bir WordPress sayfasında 60 sorguyu 8'e indirir.

    İki popüler seçenek vardır. Memcached basit ve saf bir anahtar-değer deposudur; Redis ise veri yapıları, kalıcılık ve replikasyon sunar. Kurulum ve temel kavramlar için Memcached nedir yazısı iyi bir başlangıç, ayrıntılı kurulum içinse Memcached kurulum rehberi sayfasına bakabilirsiniz. Redis tarafında hızlı bir sağlık kontrolü şöyle yapılır:

    # Bağlantı ve gecikme testi
    redis-cli ping                 # PONG dönmeli
    redis-cli --latency -i 5       # ortalama gecikme mikrosaniye seviyesinde olmalı
    
    # İsabet oranı: hit / (hit + miss)
    redis-cli info stats | grep -E "keyspace_hits|keyspace_misses"
    

    İsabet oranı (hit ratio) bu katmanın tek gerçek başarı ölçüsüdür. keyspace_hits değeriniz toplamın %85'inin altındaysa ya önbellek belleği yetersizdir ve anahtarlar erken atılıyordur ya da TTL süreleriniz çok kısadır. Bellek dolduğunda Redis'in ne yapacağını maxmemory-policy belirler; önbellek amaçlı kullanımda allkeys-lru doğru seçimdir, çünkü en az kullanılan anahtarları atar ve servisi ayakta tutar. noeviction bırakırsanız bellek dolduğu anda yazma işlemleri hata döner ve site tamamen çöker.

    Tam Sayfa Önbelleği ve Ters Vekil#

    Tam sayfa önbelleği, PHP'nin ürettiği nihai HTML'i saklar ve aynı sayfa istendiğinde PHP'yi hiç çalıştırmaz. Bu, en büyük kazancı veren katmandır: 400 ms'lik bir yanıt 20 ms'ye iner çünkü artık yapılan tek iş bir dosyayı ya da bellek bloğunu okuyup göndermektir. Nginx tarafında bu işi fastcgi_cache üstlenir ve yapılandırmanın tüm ayrıntısı için Nginx FastCGI cache yapılandırma rehberine bakmanızı öneririm. Kısa bir örnek:

    # Önbellek alanını tanımla (http bloğunda)
    fastcgi_cache_path /var/cache/nginx/fcgi levels=1:2
                       keys_zone=SITE:100m inactive=60m max_size=2g;
    
    server {
        set $skip_cache 0;
        # Giriş yapmış kullanıcı ve POST istekleri asla önbelleklenmez
        if ($request_method = POST)            { set $skip_cache 1; }
        if ($http_cookie ~* "wordpress_logged_in|woocommerce_items_in_cart") { set $skip_cache 1; }
        if ($request_uri ~* "/wp-admin/|/sepet|/odeme|/hesabim") { set $skip_cache 1; }
    
        location ~ \.php$ {
            fastcgi_cache SITE;
            fastcgi_cache_valid 200 301 302 10m;   # başarılı yanıtlar 10 dakika
            fastcgi_cache_valid 404 1m;            # 404'ü de kısa süre tut
            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache    $skip_cache;
            add_header X-Cache-Status $upstream_cache_status;  # HIT / MISS / BYPASS
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        }
    }
    

    X-Cache-Status başlığı bu kurulumun sigortasıdır. Yapılandırmayı tamamladıktan sonra curl -I https://firmaniz.com ile bu başlığı okuyun: ilk istekte MISS, ikincisinde HIT görmelisiniz. Giriş yaptıktan sonra ise BYPASS gelmelidir. Üç durumu da gözünüzle doğrulamadan önbelleğin çalıştığını varsaymayın.

    Mikro önbellek (microcaching) ise aynı mekanizmanın çok kısa TTL ile kullanılmasıdır: fastcgi_cache_valid 200 1s. Bir saniyelik önbellek bile saniyede 500 istek alan bir sayfada PHP'ye giden isteği 500'den 1'e indirir. Haber siteleri ve kampanya sayfaları gibi sürekli değişen ama anlık trafik patlaması yaşayan sayfalarda tam sayfa önbelleğinden daha uygun bir çözümdür, çünkü içerik tazeliğinden neredeyse hiç ödün vermez.

    Tarayıcı ve CDN Katmanı#

    En ucuz istek, sunucunuza hiç gelmeyen istektir. Statik dosyalar için doğru Cache-Control başlıklarını göndererek tarayıcıyı ikna edersiniz. Apache kullanıyorsanız .htaccess önbellek ve sıkıştırma yazısındaki kurallar doğrudan işinizi görür; Nginx tarafında karşılığı şudur:

    # İçerik hash'i taşıyan build çıktıları: uzun ömür + immutable
    location ~* \.(js|css|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }
    
    # Görseller: uzun ama immutable değil (dosya adı sabit olabilir)
    location ~* \.(png|jpg|jpeg|webp|svg|avif)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }
    

    immutable işaretini yalnızca dosya adında içerik hash'i olan varlıklara verin (app.9f3c1a.js gibi). Sabit adlı bir dosyaya immutable koyarsanız o dosyayı değiştirdiğinizde kullanıcı bir yıl boyunca eski sürümü görür ve tarayıcı yenilemesi bile bunu düzeltmez. Bu, sahada gördüğüm en sinsi önbellek tuzaklarından biridir.

    CDN katmanı bir adım öteye giderek dosyayı kullanıcıya coğrafi olarak yakın bir kenar sunucudan servis eder. CDN'in ne zaman anlamlı olduğunu ve hosting ile ilişkisini merak ediyorsanız CDN mi daha iyi hosting mi karşılaştırması bu kararı netleştirir. Kabaca kural şudur: ziyaretçilerinizin çoğu Türkiye'deyse ve sunucunuz da Türkiye'deyse CDN'in statik dosyalardaki katkısı sınırlıdır; ziyaretçiniz yurt dışına yayılmışsa katkı belirgindir.

    Önbellek Geçersizleştirme: İşin Zor Kısmı#

    Bilgisayar bilimlerinin klasik esprisi boşuna değildir: zor olan önbelleklemek değil, önbelleği doğru zamanda temizlemektir. Bir ürünün fiyatını güncellediniz ama site hâlâ eski fiyatı gösteriyorsa, sorun katmanlardan birinin haberdar edilmemesidir. Sağlıklı bir kurulumda içerik değiştiğinde ilgili katmanlar zincirleme temizlenir.

    Pratikte izlenecek sıra şudur:

    1. Uygulama katmanı: içerik kaydedilirken nesne önbelleğindeki ilgili anahtarları sil (WordPress'te wp_cache_delete, Laravel'de Cache::forget).
    2. Tam sayfa önbelleği: değişen URL'nin önbellek dosyasını sil. Nginx'te ücretsiz sürümde fastcgi_cache_purge yoktur; anahtarın MD5'ini hesaplayıp dosyayı silmek ya da eklenti kullanmak gerekir.
    3. CDN: kenar önbelleğini o yol için purge et.
    4. Tarayıcı: doğrudan temizleyemezsiniz; bu yüzden değişebilecek varlıkların adında hash bulunmalıdır.

    Nginx'te el ile temizlik gerektiğinde şu yaklaşım işe yarar:

    # Belirli bir URL'nin önbellek dosyasını bul ve sil
    KEY="httpsGETfirmaniz.com/urun/ornek-urun"
    HASH=$(printf '%s' "$KEY" | md5sum | cut -d' ' -f1)
    find /var/cache/nginx/fcgi -name "$HASH" -delete
    
    # Acil durumda tüm önbelleği boşalt (trafik zirvesinde dikkatli olun)
    find /var/cache/nginx/fcgi -type f -delete && systemctl reload nginx
    

    Tüm önbelleği topluca silmenin bedeli vardır: o an gelen her istek PHP'ye düşer ve "thundering herd" denilen ani yük patlaması yaşanır. Yoğun saatte tam temizlik yapmak yerine hedefli purge yapın; mecburen tam temizlik gerekiyorsa düşük trafikli saati seçin.

    Sık Yapılan Hatalar ve Tuzaklar#

    Kişiselleştirilmiş sayfayı önbelleklemek. En tehlikeli hata budur. Sepet, hesabım, sipariş özeti gibi sayfalar önbelleklenirse bir kullanıcının sepeti başka bir kullanıcıya gösterilir. Bu bir performans sorunu değil, veri sızıntısıdır. Kurulumdan sonra mutlaka farklı iki tarayıcıda giriş yapıp sayfaların birbirine karışmadığını doğrulayın.

    Set-Cookie taşıyan yanıtı saklamak. Bir yanıtta Set-Cookie başlığı varsa o yanıt neredeyse kesinlikle kişiye özeldir. Nginx yapılandırmanıza fastcgi_ignore_headers ekleyip Set-Cookie başlığını yok saymak kısa vadede önbellek isabetini artırır ama oturum çerezlerinin paylaşılmasına yol açar. Bu satırı ne yaptığınızı tam bilmeden eklemeyin.

    Katmanların TTL'lerini çelişkili ayarlamak. CDN'de 24 saat, Nginx'te 10 dakika, uygulamada 1 saat TTL varsa değişikliğin ne zaman görüneceğini kimse öngöremez. TTL'leri dıştan içe doğru artan değil, tutarlı bir hiyerarşide tanımlayın ve purge zincirini kurun.

    Önbelleği ölçmeden açmak. Katman ekledikten sonra isabet oranını izlemezseniz kurulumun çalışıp çalışmadığını bilemezsiniz. Nginx için X-Cache-Status, Redis için keyspace_hits, OPcache için opcache_get_status() çıktısını düzenli kontrol edin. Ölçmediğiniz önbellek, kurulmuş sayılmaz.

    Yavaşlığın kaynağını yanlış teşhis etmek. Sayfa yavaşlığının bir kısmı sunucu değil tarayıcı tarafındadır. Sunucu yanıtı 40 ms olduğu hâlde sayfa 6 saniyede açılıyorsa sorun render bloklayan kaynaklarda olabilir; LCP nasıl iyileştirilir yazısı bu ayrımı net biçimde ortaya koyar.

    Sıkça Sorulan Sorular#

    Hangi önbellek katmanından başlamalıyım#

    OPcache'ten başlayın; kurulumu en kolay, riski en düşük ve etkisi hemen görülen katman odur. Ardından tam sayfa önbelleğini devreye alın çünkü yanıt süresinde en büyük sıçramayı o sağlar. Nesne önbelleğini üçüncü sıraya bırakın; asıl faydası veritabanı yükünün yüksek olduğu, çok sorgulu ve dinamik sitelerde ortaya çıkar.

    Redis mi Memcached mi kullanmalıyım#

    Tek bir sunucuda basit bir nesne önbelleği kuruyorsanız ikisi arasındaki hız farkı pratikte fark edilmez. Redis'i tercih etmenizin sebebi genellikle performans değil yeteneklerdir: kalıcılık, veri yapıları, pub/sub ve replikasyon sunar. Memcached ise saf ve az bellek tüketen bir çözümdür. Uygulamanız hangisi için hazır bir sürücü sunuyorsa onunla başlayın.

    Tam sayfa önbelleği e-ticaret sitesinde güvenli mi#

    Doğru kural setiyle evet, ama varsayılan ayarlarla kesinlikle hayır. Sepet, ödeme, hesabım ve giriş yapmış kullanıcı istekleri mutlaka atlanmalıdır. Ayrıca sepetteki ürün sayısını gösteren dinamik parçalar AJAX ile ayrı bir istekte yüklenmelidir. Bu ayrımı kurmadan e-ticarette tam sayfa önbelleği açmak kullanıcıların birbirinin sepetini görmesine kadar gider.

    Önbelleği temizlediğimde site neden bir süre yavaşlıyor#

    Önbellek boşaltıldığında o ana kadar önbellekten cevaplanan tüm istekler aniden PHP'ye ve veritabanına düşer. Bu ani yük patlamasına "thundering herd" denir ve yoğun saatte yapılırsa sunucuyu kilitleyebilir. Çözüm hedefli temizlik yapmak, tam temizliği düşük trafikli saate almak ve Nginx tarafında fastcgi_cache_lock ile aynı anahtar için tek bir isteğin arka uca gitmesini sağlamaktır.

    OPcache açıkken kod değişikliklerim neden görünmüyor#

    Büyük ihtimalle opcache.validate_timestamps=0 ayarlıdır. Bu ayar PHP'ye dosya değişikliklerini kontrol etmemesini söyler ve performansı artırır ama her dağıtımdan sonra PHP-FPM'i yeniden yüklemeyi zorunlu kılar. systemctl reload php8.3-fpm komutu bytecode önbelleğini tazeler. Geliştirme sunucusunda bu ayarı 1 yapıp opcache.revalidate_freq=0 kullanmak daha rahattır.

    Paylaşımlı hostingte bu katmanların hepsini kurabilir miyim#

    Paylaşımlı hostingte OPcache genellikle sağlayıcı tarafından açıktır ve tarayıcı önbelleği için .htaccess kuralları yazabilirsiniz. Nesne önbelleği için Redis ya da Memcached sunulup sunulmadığı pakete göre değişir. Nginx fastcgi_cache gibi sunucu düzeyi ayarlar için ise root erişimi gerekir; bu katmana ihtiyacınız varsa VDS ya da sanal sunucuya geçmeniz gerekir.

    Kapanış#

    Sunucu tarafı önbellekleme tek bir eklenti değil, üst üste binen katmanlar bütünüdür. Aklınızda kalması gereken dört pratik alışkanlık şunlar: OPcache'i her zaman açık ve dosya sayınıza uygun boyutta tutun, tam sayfa önbelleğinde kişiselleştirilmiş yolları mutlaka atlayın, nesne önbelleğinizin isabet oranını düzenli ölçün ve içerik değiştiğinde temizlik zincirini uygulamadan CDN'e kadar eksiksiz çalıştırın. Bir katman eklediğinizde X-Cache-Status benzeri bir gözlem noktası bırakmadan işi bitmiş saymayın.

    Bu katmanları kendi sunucunuzda uçtan uca kurmak istiyorsanız tam root erişimi veren VDS ve sanal sunucu paketleri Nginx fastcgi_cache, Redis ve OPcache ayarlarını serbestçe yapmanıza izin verir. Kurulum ve ayar işini üstlenmemizi isterseniz sunucu yönetimi hizmetimiz önbellek katmanlarını sizin trafiğinize göre yapılandırır. WordPress tarafında hazır bir önbellek altyapısıyla başlamak isterseniz WordPress hosting paketleri OPcache ve sayfa önbelleğiyle birlikte gelir.

    ÖnbellekPerformansPHP

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.