Tüm Raporlar / API Cache Stratejisi

API Cache & Hızlandırma Stratejisi

Hangi API ne sıklıkta çağrılıyor? Hangisi cache'lenebilir?

21 Şubat 2026 v1

Altın Kural

Ödeme Yapan = ANINDA Dinler

Üye olmayan biri ödeme yaptığında 0 saniye gecikme ile müzik dinlemeye başlamalı. Bu noktada cache'lenmiş veri OLMAMALI — taze kontrol yapılmalı.

Çözüm: Ödeme onayı geldiğinde cache ANINDA temizlenir (bust)

Süresi Biten = 1-2 Saat Tolerans

Üyeliği biten bir kullanıcı 1-2 saat fazladan dinlerse sorun olmaz. Bu tolerans, cache süresini uzatmamıza ve sunucu yükünü dramatik şekilde düşürmemize olanak sağlar.

Çözüm: isPremium cache'i 2 saat — süresi biten max 2 saat fazla dinler

Bu İş Mantığı Neyi Mümkün Kılıyor?

%95
Premium kontrol istekleri cache'den karşılanır
~0ms
Yeni ödeme sonrası erişim gecikmesi
2 saat
Max. tolerans (süresi bitenler)

Ödeme → Erişim Zinciri (Şu An)

Ödeme yapıldığında sunucuda neler oluyor — bu zinciri anlamak cache stratejisinin temelidir.

1

PayTR ödeme onayı gelir (callback)

POST /api/payment-callback → hash doğrulama

Otomatik
2

Sipariş aktifleşir, abonelik oluşur

Order::activateSubscriptionItems() → Subscription oluştur/güncelle

Otomatik
3

SubscriptionObserver tetiklenir

Subscription::rechainUserSubscriptions() → tarih zinciri yeniden hesaplanır

Otomatik
4

users.subscription_expires_at güncellenir

User::recalculateSubscriptionExpiry() → Tüm aboneliklerin en son bitiş tarihi yazılır

Otomatik
5

Cache BUST — isPremium cache'i ANINDA temizlenir

YENİ EKLENECEK → recalculateSubscriptionExpiry() içinde Redis::forget("user:{id}:is_premium")

Yeni Adım

Kullanıcı şarkı çalar → isPremium() = taze sorgu → cache'e yaz (2 saat)

İlk istek DB'ye gider, sonraki 2 saat boyunca cache'den döner

Sonuç

Basit anlatım: Ödeme geldiğinde sistem zaten otomatik olarak subscription tablosunu ve users tablosunu güncelliyor. Tek yapmamız gereken: bu güncelleme anında cache'i de temizlemek. Sonraki şarkı çalma isteği taze DB'den okur ve "premium" olarak cache'ler.


Tüm API Endpoint'leri — Frekans & Cache Haritası

Yüksek = Her şarkıda   Orta = Sayfa/oturum bazlı   Düşük = Nadiren

Şu an: Cache yok | Öneri: Cache eklenecek

Her Şarkıda Çağrılan (Kritik Yol)

Kullanıcı her şarkıyı çaldığında bu endpoint'ler sırayla tetiklenir. En çok optimize edilmesi gereken grup.

HER ŞARKI /api/muzibu/songs/{id}/stream
~200-500ms

Premium kontrolü + stream URL oluşturma + şifreleme

Şu an
  • isPremium() → her seferinde taze DB sorgusu
  • Şarkı verisi → Redis 24 saat (iyi)
  • URL imzalama → her seferinde hesaplanıyor
Öneri
  • isPremium() → Redis 2 saat (ödeme anında bust)
  • Şarkı verisi → Redis 24 saat (değişmez)
  • URL imzalama → her seferinde (güvenlik gereği)

Kazanç: ~30-50ms/istek (DB sorgusu kalkıyor)

HER ŞARKI /api/muzibu/hls/key/{songId}
~20-50ms

HLS şifreleme anahtarı (16 byte binary) — HLS.js otomatik çağırır

Şu an
  • Anahtar → Redis 24 saat
  • Fallback → diskten okuma (enc.bin)
Öneri
  • Zaten cache'li — İyi durumda
  • Soft Mode'da bu istek tamamen kalkar (MP3)

Not: MP3 modunda bu endpoint hiç çağrılmaz — HLS'e özel

HER ŞARKI /api/muzibu/hls/serve/{songId}/{file}
~100-300ms

HLS playlist (m3u8) ve segment (ts) dosyalarını sunar — HLS.js otomatik çağırır

Şu an
  • Playlist → her seferinde diskten + regex
  • Segment → immutable header (CDN friendly)
Öneri
  • Playlist şablonu → Redis 24 saat
  • Soft Mode'da bu istek tamamen kalkar (MP3)

Not: MP3 modunda bu endpoint hiç çağrılmaz — HLS'e özel

HER ŞARKI /api/muzibu/songs/{id}/track-start
~50-150ms

Çalma kaydı oluşturur (Faz 1/3) — 3 DB sorgusu (şarkı kontrol + duplikat kontrol + insert)

Şu an
  • await fetch() → player stream başladıktan SONRA
  • Senkron bekleme (hızı etkilemiyor)
Öneri
  • Queue'ya at (Laravel Job)
  • Anında 200 dön, arka planda yaz

Kazanç: ~100ms (3 DB sorgusu arka plana taşınır)

30 SANİYEDE BİR /api/muzibu/songs/{id}/track-hit
~50-100ms

30 saniye dinleme markı (Faz 2/3) — play_count artırır

Şu an
  • Zaten setTimeout (30s) ile arka planda
Öneri
  • Queue'ya at — play_count Redis'te artır, periyodik DB sync
HER ŞARKI SONU /api/muzibu/songs/{id}/track-end
~50-100ms

Dinleme sonu/atlama kaydı (Faz 3/3) — sendBeacon ile fire-and-forget

Şu an
  • Zaten sendBeacon — fire-and-forget, UI bloklamaz
Öneri
  • Zaten iyi — opsiyonel queue

Sayfa/Oturum Bazlı Çağrılan

Kullanıcı sayfayı açtığında veya uygulamaya döndüğünde çağrılır. Şarkı başına değil, oturum başına.

SAYFA AÇILIŞ /api/muzibu/songs/recent
~200-500ms

Son dinlenen şarkılar — 2-3 DB sorgusu, CACHE YOK

Şu an
  • Her seferinde 2-3 taze DB sorgusu
  • JOIN + eager loading + sıralama
Öneri
  • Redis 5 dakika (kullanıcı bazlı)
  • trackStart'ta cache bust (yeni şarkı çalındı)

Kazanç: ~200-400ms (2-3 DB sorgusu tamamen kalkar)

SAYFA AÇILIŞ /api/muzibu/songs/popular
~100-300ms

Popüler şarkılar — şu an cache YOK (ama 30dk olabilir)

Şu an
  • Her seferinde DB sorgusu (play_count sıralaması)
Öneri
  • Redis 30 dakika (herkes için aynı)

Kazanç: ~100-300ms + DB yükü azalır (tüm kullanıcılar ortak cache)

SAYFA AÇILIŞ /api/muzibu/songs/last-played
~50-150ms

Son çalınan şarkı (preload) — şarkı verisi Redis'te, play kaydı DB'de

Şu an
  • Şarkı → Redis (24h), play → DB sorgusu
Öneri
  • Redis 5 dk (komple yanıt cache)
SAYFA AÇILIŞ /api/muzibu/queue/initial
~100-300ms

Başlangıç çalma kuyruğu — 2-3 DB sorgusu

Şu an
  • Her seferinde taze kuyruk hesaplaması
Öneri
  • Redis 10 dakika (kullanıcı bazlı)

Nadiren Çağrılan (Düşük Öncelik)

Kullanıcı gezinirken, arama yaparken çağrılır. Sıklığı düşük, optimizasyon önceliği düşük.

Endpoint Ne Zaman Şu An Öneri
/albums Albüm sayfası Cache yok Redis 15 dk
/artists Sanatçı sayfası Cache yok Redis 15 dk
/genres Tür sayfası Cache yok Redis 1 saat
/playlists Playlist sayfası Cache yok Redis 10 dk
/songs/{id} Şarkı detayı (queue restore) Cache yok Redis 1 saat
/ratings Beğeni/puan Cache yok Cache gerekmez (yazma)

Öncelik Sırası & Beklenen Etki

En çok etki yaratacak değişiklikler önce, en az efor ile en büyük kazanç.

1

isPremium() Redis Cache (2 Saat)

EN YÜKSEK ETKİ KOLAY

Her şarkı çalma isteğinde yapılan DB sorgusu ortadan kalkar. Günde 10.000 şarkı çalınıyorsa = 10.000 DB sorgusu → 0'a düşer.

2 saat
Cache TTL
~30-50ms
İstek başına kazanç
~0ms
Yeni üye gecikmesi
~30dk
Geliştirme süresi
// User.php → isPremium() değişikliği
Cache::remember("user:{$this->id}:is_premium", 7200, function() {
return $this->subscription_expires_at?->isFuture() ?? false;
});
// recalculateSubscriptionExpiry() sonuna ekle:
Cache::forget("user:{$this->id}:is_premium");
2

recent + popular + lastPlayed Cache

ORTA ETKİ KOLAY

Sayfa açılış hızını dramatik artırır. 3 endpoint birden cache'lenince sayfa yüklenme ~500ms daha hızlı.

recent
Kullanıcı bazlı, 5 dk TTL, trackStart'ta bust
popular
Global, 30 dk TTL, tüm kullanıcılar ortak
lastPlayed
Kullanıcı bazlı, 5 dk TTL, trackStart'ta bust
3

Tracking Queue (trackStart arka plana)

ORTA ETKİ ORTA ZORLUK

trackStart 3 DB sorgusu yapıyor. Bunu Laravel Queue'ya taşırsak: API anında 200 döner, DB yazımları arka planda olur. Kullanıcı farkı hissetmez.

trackStart
Queue'ya taşı → ~100ms kazanç
trackHit
Redis increment → periyodik DB sync
trackEnd
Zaten sendBeacon — opsiyonel queue
4

HLS Playlist Şablon Cache

HLS KULLANANLAR İÇİN

serveHls her çağrıda diskten m3u8 okuyup regex ile URL'leri yeniden yazıyor. Playlist şablonunu Redis'te tutarsak disk I/O + regex overhead kalkar. Not: MP3/Soft Mode'da zaten HLS kullanılmaz — bu optimizasyon sadece HLS kullanıcıları için.


Toplam Etki — Önce vs Sonra

Şarkı Çalma Akışı (Stream Tıkla → Ses Gelir)

İşlem Şu An Cache Sonrası Soft Mode (MP3)
isPremium kontrolü ~30-50ms (DB) ~1ms (Redis) ~1ms (Redis)
Stream URL oluşturma ~50-100ms ~50-100ms ~30-50ms (daha basit)
HLS key isteği ~20-50ms ~5ms (Redis) 0ms (gerek yok)
HLS playlist isteği ~100-200ms (disk+regex) ~10-20ms (Redis) 0ms (gerek yok)
İlk segment/MP3 yükleme ~100-300ms ~100-300ms ~50-150ms (tek dosya)
trackStart kaydı ~50-150ms (await) ~5ms (queue) ~5ms (queue)
TOPLAM (ses gelene kadar) ~350-850ms ~170-430ms ~85-205ms
~600ms
Şu An (Ortalama)
Her şarkıda 4 ardışık istek + DB
~300ms
Cache Sonrası (HLS)
%50 iyileşme — aynı HLS akışı
~150ms
Soft Mode (MP3)
%75 iyileşme — tek istek

Cache Temizleme (Invalidation) Haritası

Her cache ne zaman temizlenecek — yanlış/eski veri göstermemek için kritik.

Cache Key TTL Ne Zaman Bust? Tolerans
user:{id}:is_premium 2 saat Ödeme onayı, abonelik değişikliği Biten üye max 2 saat fazla dinler
user:{id}:recent_songs 5 dk Yeni şarkı çalındığında (trackStart) 5 dk eski liste görebilir — sorun değil
user:{id}:last_played 5 dk Yeni şarkı çalındığında (trackStart) Önceki şarkı preload olur — sorun değil
global:popular_songs 30 dk TTL ile otomatik yenilenir 30 dk eski sıralama — sorun değil
user:{id}:initial_queue 10 dk TTL ile otomatik yenilenir Kuyruk biraz eski — sorun değil
song:{id}:hls_key 24 saat Asla (key değişmez) Key sabit — tolerans gerekmez
song:{id}:playlist_tpl 24 saat HLS yeniden dönüştürülürse Playlist sabit — tolerans gerekmez

Rate Limiting & Sınırlama Stratejisi

Her endpoint'in makul bir çağrı sınırı olmalı — hem kötü niyetli kullanımı önler, hem sunucu korunur.

Endpoint Mevcut Limit Önerilen Limit Mantık
/stream throttle.user:stream 60/saat Dakikada 1 şarkı = saatte max 60 (gerçekçi)
/track-start Yok 60/saat /stream ile aynı oranda (1:1)
/track-hit Yok 120/saat 30 saniyede 1 = 3 dakikalık şarkıda 6 hit
/track-end Yok 60/saat /stream ile aynı oranda
/recent Yok 30/saat Sayfa yenileme sıklığı (cache'le bile korunmalı)
/popular Yok 30/saat Global cache'li — sık çağrıya gerek yok
/hls-key, /hls/serve Yok 120/saat HLS.js çoklu istek yapar — toleranslı