Eğer file_exists($path) fonksiyonunu çağırırsanız ve $path bir Amazon S3 bucket'ına işaret ediyorsa, yerel bir diske erişmiyorsunuz demektir; bir ağ isteği yapıyorsunuzdur. Tek satırlık bu kontrol, her isteğe onlarca milisaniye ekleyebilecek bir S3 gidiş-dönüş (round-trip) işlemine dönüşür.

PHP, uzak depolama birimini stream wrapper'lar (akış sarmalayıcılar) arkasına gizler. fopen(), file_exists(), is_dir(), unlink() ve file_put_contents() gibi fonksiyonlar, bu çağrıları S3 API işlemlerine dönüştüren bu sarmalayıcılar üzerinden yönlendirilir. Eşleşme oldukça basittir:

  • file_exists()HeadObject
  • is_dir()ListObjects
  • unlink()DeleteObject
  • file_put_contents()PutObject

Her çağrı, ilgili S3 API isteğiyle aynı gecikmeye (latency) neden olur. Bir betik onlarca dosyayı kontrol ettiğinde, N+1 tarzı bir desen oluşturur: her bir kontrol için tek bir ağ sıçraması (network hop).

Neden şimdi önemli

Tipik bir geliştirme ortamında dosya sistemi aynı makinede bulunur, bu nedenle kontrol neredeyse anında sonuçlanır. Varlıkların (assets) S3 üzerinde bulunduğu üretim (production) ortamında ise aynı kod bir performans uçurumuna neden olur. AWS SDK, bazı sonuçları bellekte önbelleğe alarak tek bir PHP işlemi içindeki tekrarlanan kontrollerin hızlı görünmesini sağlar. Ancak çoğu PHP dağıtımı, her web isteği için yeni bir işlem başlatır ve her seferinde önbelleği temizler. Sonuç: her istekte her farklı yol için tam bir ağ gidiş-dönüş işlemi.

Bir WordPress sitesi, ana sayfasını oluşturmak için bir zamanlar on saniye harcıyordu. Veritabanı sorguları hızlıydı ancak sayfa, içeriği oluşturmak için sadece 73 ayrı S3 çağrısı tetikliyordu. Her çağrı "soğuk" (cold) bir istekti ve görünüşte zararsız olan file_exists() fonksiyonunu fark edilir bir gecikmeye dönüştürüyordu.

Azaltma stratejileri

  • Önbelleği istekler arasında kalıcı hale getirin – İşlem içi (in-process) önbelleği Redis gibi paylaşılan bir depolama birimine taşıyın. Bir istek, bir anahtarın S3'te mevcut olduğunu keşfettiğinde, sonraki istekler S3 ile tekrar iletişime geçmek yerine önbelleğe alınmış sonucu okur.
  • Önce yerel (local-first) bir iş akışı benimseyin – Dosyaları yerel bir diske yazın, ardından bunları asenkron olarak S3 ile senkronize edin. Ana istek yolu yalnızca yerel dosya sistemine dokunur; ağ maliyeti bir arka plan işine (background job) kaydırılır.
  • Kod tabanını denetleyin – Uzak bir sarmalayıcıya (remote wrapper) dönüşebilecek dosya sistemi fonksiyonlarını sistematik olarak arayın. Sık döngüler (tight loops) veya istek için kritik yollar içinde görünenleri işaretleyin.
  • APM verilerini inceleyin – Veritabanı metrikleri sabit kalırken yanıt süresi aniden yükselirse, depolama SDK zamanlamalarını derinlemesine inceleyin. SDK gecikmesindeki ani bir artış genellikle gizli S3 çağrılarına işaret eder.

Temel çıkarım: Mikrosaniye düzeyinde yerel bir kontrol gibi görünen bir fonksiyon, onlarca milisaniyelik ağ gecikmesini gizleyebilir. S3 üzerindeki file_exists() kullanımını harici bir çağrı olarak değerlendirin, sonucunu önbelleğe alın ve ağır iş yükünü istek yolunun dışına taşıyın. Aksi takdirde, gizli gecikmeler sitenizi her seferinde görünmez bir ağ isteğiyle yavaşlatmaya