Cloudflare Cache Rules ile İçerik Önbellekleme
Cloudflare üzerinde çalışırken en çok gözden kaçan ama performans açısından en kritik özelliklerden biri Cache Rules sistemidir. Eskiden Page Rules ile yapılan önbellekleme ayarları artık çok daha esnek ve güçlü bir yapıya kavuştu. Bu yazıda Cache Rules’u sıfırdan anlayacak, gerçek dünya senaryolarıyla nasıl kullanacağınızı öğrenecek ve site performansınızı ciddi ölçüde artıracaksınız.
Cache Rules Nedir ve Neden Önemlidir
Cloudflare’nin edge ağı üzerinde içeriklerinizin nasıl önbellekleneceğini belirleyen kural sistemidir Cache Rules. Normalde Cloudflare, statik dosyaları (CSS, JS, resimler) otomatik olarak önbellekler ama HTML sayfaları, API yanıtları ve dinamik içerikler için herhangi bir şey yapmaz. İşte burada devreye giriyoruz.
Neden bu kadar önemli? Şöyle düşünün: Bir e-ticaret siteniz var, günde 50.000 ziyaretçi geliyor. Her ziyaretçi kategori sayfasını açtığında sunucunuz veritabanına sorgu atıyor, PHP çalıştırıyor, HTML üretiyor. Oysa o kategori sayfasının içeriği belki 5 dakikada bir değişiyor. Cache Rules ile o sayfayı Cloudflare edge’lerinde 5 dakika tutarsanız, sunucunuza gelen yükü dramatik biçimde düşürürsünüz.
Eski Page Rules sisteminden farkı ise şu: Page Rules maksimum 3 ücretsiz kural hakkı veriyordu ve çok kaba bir yapıydı. Cache Rules ise ayrı bir bölümde, çok daha granüler kontrol sunuyor. URL pattern eşleştirme, HTTP başlık kontrolü, cookie bazlı mantık kurma gibi gelişmiş özellikler artık çok daha kolay erişilebilir durumda.
Cache Rules Arayüzüne Erişim
Cloudflare dashboard’a giriş yaptıktan sonra ilgili domain’i seçin. Sol menüden Caching bölümüne tıklayın, ardından Cache Rules seçeneğini bulacaksınız. Burada mevcut kurallarınızı görüntüleyebilir, yeni kural ekleyebilir ve sıralama yapabilirsiniz.
Kuralların sıralaması kritik önem taşır. Cloudflare kuralları yukarıdan aşağıya doğru işler ve ilk eşleşen kuralı uygular. Yani özel kurallarınızı genel kuralların üstüne koymanız gerekir. Bu noktayı aklınızın bir köşesine yazın, ileride çok işinize yarayacak.
Temel Cache Rule Yapısı
Bir Cache Rule oluştururken üç temel bileşen var:
- When incoming requests match: Hangi isteklere uygulanacak (koşul)
- Cache eligibility: İçeriğin önbelleğe alınıp alınmayacağı
- Edge TTL: Cloudflare edge’lerinde ne kadar tutulacağı
- Browser TTL: Ziyaretçinin tarayıcısında ne kadar tutulacağı
- Cache Key: Önbellek anahtarının nasıl oluşturulacağı
Cloudflare’nin kendi API’sini kullanarak kural oluşturmak isterseniz şu yapıyı kullanabilirsiniz:
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "Cache HTML pages 5 minutes",
"expression": "(http.request.uri.path matches "^/kategori/")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "override_origin",
"default": 300
},
"browser_ttl": {
"mode": "override_origin",
"default": 60
}
}
}'
Gerçek Dünya Senaryo 1: WordPress Sitesi Optimizasyonu
Diyelim ki bir WordPress siteniz var. WordPress’in en büyük sorunlarından biri her sayfa isteğinde PHP çalıştırması. Ama giriş yapmış kullanıcılar, yorum yapanlar ve sepette ürün bulunanlar için dinamik içerik şart. Geri kalan herkese cache servis edebiliriz.
Önce WordPress için temel cache kuralını API üzerinden görelim:
# WordPress admin, login ve dinamik sayfalar icin cache devredisi birak
# Bu kural oncelikli olmali
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "WordPress - Admin ve dinamik sayfalar bypass",
"expression": "(http.request.uri.path contains "/wp-admin") or (http.request.uri.path contains "/wp-login") or (http.request.uri.path contains "/wp-json") or (http.cookie contains "wordpress_logged_in") or (http.cookie contains "woocommerce_cart")",
"action": "set_cache_settings",
"action_parameters": {
"cache": false
}
}'
Ardından genel sayfa önbelleklemesi için ikinci kuralı oluşturuyoruz:
# WordPress genel sayfalari 10 dakika cachele
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "WordPress - Genel sayfalar cache",
"expression": "(http.host eq "siteniz.com") and (http.request.uri.path matches "^/[^?]*$")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "override_origin",
"default": 600
},
"browser_ttl": {
"mode": "override_origin",
"default": 300
},
"cache_key": {
"ignore_query_strings_order": false,
"cache_by_device_type": false,
"cache_deception_armor": true
}
}
}'
Gerçek Dünya Senaryo 2: API Endpoint’leri için Cache
Bir REST API sunuyorsunuz ve bazı endpoint’lerin sonuçları sık değişmiyor. Örneğin ürün listesi endpoint’i her istekte veritabanını döverek aynı veriyi döndürüyor. Bunu önbelleğe almak hem sunucu yükünü düşürür hem de API yanıt süresini millisaniyelere indirir.
# Urün listesi API endpoint - 2 dakika cache
# Cache-Control header'ini da override et
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "API - Urun listesi 2 dakika cache",
"expression": "(http.request.uri.path matches "^/api/v[0-9]+/products") and (http.request.method eq "GET")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "override_origin",
"default": 120
},
"browser_ttl": {
"mode": "bypass"
},
"cache_key": {
"custom_key": {
"query_string": {
"include": ["page", "limit", "sort", "category"]
}
}
}
}
}'
Burada dikkat çeken nokta cache_key konfigürasyonu. Sadece belirli query string parametrelerini cache key’e dahil ediyoruz. Böylece ?page=1&limit=20&utm_source=google ile gelen istek, ?page=1&limit=20 ile aynı cache’i kullanıyor. UTM parametreleri gereksiz yere farklı cache entry’leri oluşturmuyor.
Cache Key Özelleştirme
Cache key, Cloudflare’nin bir içeriği depolama ve bulma amacıyla kullandığı benzersiz tanımlayıcıdır. Varsayılan olarak URL’nin tamamını kullanır. Bunu özelleştirmek büyük avantaj sağlar.
Örneğin mobil ve masaüstü kullanıcılara farklı içerik servis eden bir siteniz varsa:
# Mobil/masaustu icin farkli cache key olustur
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "Device type bazli cache key",
"expression": "(http.host eq "siteniz.com")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "override_origin",
"default": 3600
},
"cache_key": {
"cache_by_device_type": true,
"custom_key": {
"header": {
"include": ["Accept-Language"]
},
"cookie": {
"include": ["user_currency"]
}
}
}
}
}'
Bu kural cihaz tipini, Accept-Language header’ini ve user_currency cookie’sini cache key’e ekliyor. Türkçe/İngilizce ve TL/USD gibi farklı kombinasyonlar için ayrı cache entry’leri oluşturulacak.
TTL Stratejileri
TTL (Time To Live) değerlerini doğru belirlemek bir sanattır. Çok kısa tutarsanız cache hit rate düşer, çok uzun tutarsanız güncel olmayan içerik servis edersiniz.
Genel bir rehber olarak şu yaklaşımı önerebilirim:
- Statik dosyalar (CSS, JS, resimler): 30 gün veya daha fazla, versiyonlama ile kullanın
- HTML sayfaları (haber siteleri): 5-15 dakika
- HTML sayfaları (kurumsal siteler): 1-4 saat
- API yanıtları (sık değişen veri): 1-5 dakika
- API yanıtları (nadiren değişen veri): 15-60 dakika
- Statik sayfa içerikleri: 24 saat
Cloudflare’de origin sunucunuzun gönderdiği Cache-Control başlığına saygı gösterip göstermeyeceğinizi de seçebilirsiniz. override_origin modu origin’i tamamen ignore eder, respect_origin ise origin’in dediğini yapar ama bir alt sınır koyabilirsiniz.
# Origin Cache-Control'e saygi goster ama minimum 60 saniye zorla
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "Statik dosyalar - Origin TTL ile minimum 60s",
"expression": "(http.request.uri.path matches "\.(css|js|woff2|woff|ttf)$")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "respect_origin_with_no_max_age_behavior",
"default": 60
},
"browser_ttl": {
"mode": "respect_origin"
}
}
}'
Cache Purge Stratejisi
İçeriği önbellekledikten sonra güncellendiğinde ne yapacaksınız? Cache purge işlemi bunun için var. İki yöntem var: tag bazlı purge ve URL bazlı purge.
Tag bazlı purge için önce origin sunucunuzdan yanıtlara Cache-Tag header’i eklemeniz gerekiyor. Örneğin bir WordPress eklentisi ya da nginx konfigürasyonu ile:
# Nginx - belirli lokasyonlar icin cache tag ekle
# /etc/nginx/sites-available/siteniz.com dosyasina ekleyin
location /kategori/ {
add_header Cache-Tag "kategori-sayfasi";
proxy_pass http://backend;
}
location /urun/ {
add_header Cache-Tag "urun-sayfasi";
proxy_pass http://backend;
}
Ardından Cloudflare API ile tag bazlı purge:
# Belirli tag ile isaretlenmis cache'leri temizle
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"tags": ["kategori-sayfasi"]
}'
URL bazlı purge ise daha basit:
# Belirli URL'lerin cache'ini temizle
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"files": [
"https://siteniz.com/blog/yeni-makale",
"https://siteniz.com/urunler/laptop-modeli-x"
]
}'
Deployment pipeline’ınıza bu purge komutunu eklemek iyi bir pratiktir. Yeni versiyon deploy ettikten sonra otomatik olarak cache temizlensin.
Hata Ayıklama ve Cache Status Kontrol
Cache Rules doğru çalışıyor mu? Bunu kontrol etmek için response header’larına bakmanız yeterli:
# Sitenizin cache durumunu kontrol et
curl -I "https://siteniz.com/blog/ornek-yazi"
-H "User-Agent: Mozilla/5.0" 2>/dev/null | grep -i "cf-cache|age|cache-control|x-cache"
# Beklenen cikti ornegi:
# cf-cache-status: HIT
# age: 245
# cache-control: max-age=600
# x-cache: HIT
cf-cache-status header’ının alabileceği değerler:
- HIT: İçerik cache’ten servis edildi, harika!
- MISS: Cache’te yoktu, origin’den çekildi
- BYPASS: Cache atlandı (sizin kuralınız veya origin header’ı nedeniyle)
- EXPIRED: Cache’teydi ama süresi dolmuştu, yenilendi
- REVALIDATED: Yeniden doğrulandı ve hala geçerli
- DYNAMIC: Cloudflare bu içeriği önbelleğe almıyor
- STALE: Süresi dolmuş ama origin erişilemez, eski içerik servis edildi
Düşük cache hit rate’i sorununu araştırırken şu nginx log analizini kullanabilirsiniz:
# Origin sunucuya gelen isteklerin hangi URL'lerden oldugunu analiz et
# Bu istekler cache'e takilmayan isteklerdir
tail -n 10000 /var/log/nginx/access.log |
awk '{print $7}' |
sort |
uniq -c |
sort -rn |
head -20
Eğer yukarıdaki çıktıda aynı URL’ler sürekli görünüyorsa, o URL’ler cache’e girmiyor demektir. Cloudflare dashboard’daki Analytics bölümünde de Cache Analytics sekmesinden hit/miss oranlarını grafik olarak izleyebilirsiniz.
Gelişmiş Senaryo: Coğrafi Konum Bazlı Cache
Cloudflare Enterprise planında coğrafi konum bazlı cache key oluşturabilirsiniz. Ama Free/Pro/Business planlarında da bir miktar bunu taklit edebilirsiniz:
# Ulke bazli farkli cache davranisi
# Turkiye'den gelen istekler icin ozel kural
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint/rules"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '{
"description": "Turkiye trafigi icin uzun cache",
"expression": "(ip.geoip.country eq "TR") and (http.request.uri.path matches "^/tr/")",
"action": "set_cache_settings",
"action_parameters": {
"cache": true,
"edge_ttl": {
"mode": "override_origin",
"default": 7200
},
"browser_ttl": {
"mode": "override_origin",
"default": 1800
}
}
}'
Sık Yapılan Hatalar
Yanlış kural sıralaması: En spesifik kurallar en üstte olmalı. Eğer bypass kuralınız cache kuralından sonra geliyorsa, login olmuş kullanıcılara da cache servis edersiniz. Bu hem güvenlik hem de kullanıcı deneyimi açısından felaket olabilir.
Query string’i göz ardı etmek: ?page=1 ile ?page=2 farklı içerikler döndürüyor ama siz query string’i cache key’den çıkardıysanız her kullanıcı aynı sayfayı görür. Hangi query string parametrelerinin anlamlı olduğunu dikkatle belirleyin.
Cookie kontrolü eksikliği: Özellikle e-ticaret sitelerinde sepet, kullanıcı oturumu ve kişiselleştirilmiş içerik cookie’leri hayati önem taşır. Bu cookie’ler varken cache’i bypass etmeyi unutmayın.
Origin header’larıyla çakışma: Sunucunuzdan no-cache veya private gönderiyorsanız ve Cloudflare’de respect_origin modunu kullanıyorsanız, Cache Rules’unuz işe yaramaz. Override moduna geçmeniz gerekebilir.
Test etmeden production’a almak: Her zaman staging ortamında test edin. Yanlış bir kural, tüm sitenizi bozuk içerikle servis edebilir.
Cache Rules ile Performans Kazanımları
Gerçek bir proje örneği: Orta ölçekli bir haber sitesi, günde yaklaşık 200.000 sayfa görüntülenmesi alıyordu. Cache Rules devreye almadan önce sunucu CPU kullanımı ortalama yüzde 75’ti, average response time 800ms civarındaydı.
Cache Rules konfigürasyonu sonrası:
- Cache hit rate yüzde 78’e çıktı
- Sunucu CPU kullanımı yüzde 22’ye düştü
- Average response time 120ms’ye indi
- Origin’e giden istek sayısı günlük 200.000’den 44.000’e düştü
- Bandwith maliyeti yüzde 40 azaldı
Bu rakamlar dramatik görünebilir ama içerik üretim hızı yüksek ve büyük çoğunluğu okuma işlemi olan siteler için oldukça gerçekçi sonuçlar.
Monitoring ve Alerting
Cache kurallarınız devrede, her şey yolunda mu? Bunu sürekli izlemek için basit bir monitoring scripti:
#!/bin/bash
# cache_monitor.sh - Cache hit rate kontrolu
ZONE_ID="ZONE_ID_BURAYA"
API_TOKEN="TOKEN_BURAYA"
ALERT_THRESHOLD=50 # Yuzde 50 altinda uyari ver
# Son 1 saatin cache istatistiklerini cek
RESPONSE=$(curl -s "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/analytics/dashboard?since=-60&until=0"
-H "Authorization: Bearer ${API_TOKEN}")
CACHED=$(echo $RESPONSE | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['totals']['requests']['cached'])")
UNCACHED=$(echo $RESPONSE | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['totals']['requests']['uncached'])")
TOTAL=$((CACHED + UNCACHED))
if [ $TOTAL -gt 0 ]; then
HIT_RATE=$(echo "scale=2; ($CACHED * 100) / $TOTAL" | bc)
echo "Cache Hit Rate: %${HIT_RATE}"
if (( $(echo "$HIT_RATE < $ALERT_THRESHOLD" | bc -l) )); then
echo "UYARI: Cache hit rate %${ALERT_THRESHOLD} altinda! Mevcut: %${HIT_RATE}"
# Buraya mail/Slack/PagerDuty entegrasyonu ekleyebilirsiniz
fi
fi
Bu scripti cron ile her 30 dakikada bir çalıştırabilirsiniz:
# Crontab'a ekle
*/30 * * * * /usr/local/bin/cache_monitor.sh >> /var/log/cache_monitor.log 2>&1
Sonuç
Cloudflare Cache Rules, doğru konfigüre edildiğinde sitenizin performansını ve sunucu maliyetlerinizi inanılmaz biçimde iyileştirir. Ama dikkat edilmesi gereken ince noktalar var: Kural sıralaması, cookie ve query string yönetimi, purge stratejisi ve düzenli monitoring bunların başında geliyor.
Başlangıç için şu adımları izlemenizi öneririm: Önce mevcut cache durumunuzu cf-cache-status header’larını kontrol ederek anlayın. Ardından bypass edilmesi gereken URL’leri ve cookie’leri belirleyin. İlk kurallarınızı staging ortamında test edin ve cache hit rate’i izleyin. Sonra production’a geçin ve Analytics üzerinden sonuçları gözlemleyin.
Cache Rules, bir kere doğru kurulduğunda büyük ölçüde “kur ve unut” sistemi olarak çalışır. Tabii ki içerik yapınız değiştikçe kurallarınızı güncellemeniz gerekecek ama günlük yönetim gerektirmez. Sunucularınıza biraz nefes aldırmanın ve ziyaretçilerinize daha hızlı bir deneyim sunmanın en kolay yollarından biridir.
