opcache preload deploy faturasını on dört kata kadar siliyor — ama yedi framework'ün beşi onu size vermiyor
`opcache.preload` açıkken yedi PHP framework'ünün deploy sonrası ilk isteği ne kadar sürüyor, bu kazanç neye mal oluyor, ve kimler ona erişebiliyor?
Bulgu
Preload, soğuk ilk isteği 3,5 ile 14,2 kat arasında kısaltıyor: Symfony 35,58 ms'den 2,50 ms'ye, yani Phalcon'un çıplak seviyesine iniyor. Ama yedi adayın yalnız ikisi (Symfony, CodeIgniter) resmî bir preload dosyası yayınlıyor; kalan beşinde kazanç masada duruyor ve kullanıcının kendi yazmasını bekliyor. Yazmak da göründüğü kadar kolay değil: classmap'ten körlemesine üretilen preload Symfony'yi hiç ayağa kaldırmıyor, CodeIgniter'da ise elle seçilmiş resmî dosyadan (3,13 ms) daha kötü sonuç veriyor (5,29 ms). Ve bedel kaybolmuyor: Laravel'in classmap preload'ı ziyaretçiden aldığı 62 ms'yi php-fpm'in ayağa kalkışına 2.340 ms olarak yazıyor.
- Symfony, soğuk ilk istek
- 2,50 ms −%93
- Resmî preload taşıyan aday
- 2 / 7
- Laravel classmap, fpm bedeli
- +2.340 ms
- Elle seçim vs hepsini derle
- 3,13 → 5,29 ms
Yöntem
Ayak izi ve yük ölçümleriyle birebir aynı imajlar, aynı PHP 8.4 derlemesi, aynı nginx + php-fpm yığını. Hiçbir imaj yeniden derlenmedi: opcache `conf.d`'yi sırayla okuduğu için çalışma anında mount edilen bir `02-*.ini`, imaja gömülü `00-bench-opcache.ini`'yi eziyor. Aday başına üç varyant koşuldu — preload yok, framework'ün kendi dosyası (konteyner içinde aranarak bulunur, elle yazılmaz), ve Composer classmap'indeki her sınıfı `opcache_compile_file` ile derleyen tek tip bir dosya. Her varyant için taze konteyner ayağa kaldırıldı ve **konteynerin sunduğu ilk istek** ölçüldü; hazırlık yoklamasının kendisi o istektir, çünkü ayrı bir yoklama ilk isteği harcayıp geriye sıcak bir ölçüm bırakıyor. Üç tekrar, medyan raporlanıyor. Preload'ın bedeli php-fpm'in ilk 200 yanıtı verene kadar geçen süreyle ölçülüyor; bu pencere nginx'in kendi açılışını da içeriyor ama üç varyantta da aynı sabit. Doğrulama: `preload yok` varyantı 20 Ağustos'ta yayınlanan bağımsız koşunun soğuk sayılarını ±%6 içinde yeniden üretiyor.
- Ölçüm tarihi
- Yayın
dün ölçüldü
Ortam
- PHP
- 8.4.24 NTS · opcache açık · JIT kapalı
- opcache
- validate_timestamps=0 · 256 MB · preload varyanta göre açık/kapalı
- Sunucu
- nginx 1.29.1 + php-fpm · pm=static · 8 worker
- Donanım
- Apple M4 Pro · 12 çekirdek · 24 GB · macOS 26.6.1
- Sanallaştırma
- Docker Desktop 29.7.2 · aarch64
- Tekrar
- 3 · medyan raporlanır
- Temel çizgi doğrulaması
- 2026-08-20 koşusuna göre ±%6
Teknolojiler
Tekrarlamak için
REPEATS=3 ./bench/preload.sh Ayak izi ölçümü bir sayı bırakmıştı: taze bir konteynerin karşıladığı ilk istekte Phalcon 2,2 ms, Laravel 72,2 ms — otuz üç kat. Deploy’dan sonraki ilk ziyaretçinin ödediği derleme faturası bu. Aynı kaydın ortam künyesinde de bir satır vardı: preload yok.
Bu kayıt o satırı kapatıyor. Tek değişken.
Kazanç
Deploy sonrası ilk isteğin süresi, preload açık ve kapalıyken
Her adayın en iyi preload varyantı gösteriliyor: Symfony ve CodeIgniter'da kendi resmî dosyaları, diğerlerinde classmap'ten üretilen tavan.
- preload yok
- preload açık
ms düşük olan iyi Kaynak: bench/preload.sh, üç tekrarın medyanı
Veri tablosu
| Seri | Laravel | Symfony | Laminas | CodeIgniter | Yii2 | Slim | Phalcon |
|---|---|---|---|---|---|---|---|
| preload yok | 76,31 ms | 35,58 ms | 26,7 ms | 20,75 ms | 16,98 ms | 7,46 ms | 2,68 ms |
| preload açık | 13,98 ms | 2,5 ms | 3,81 ms | 3,13 ms | 4,8 ms | 1,86 ms | 1,99 ms |
Grafik tarayıcıda çizilir; aşağıdaki tablo aynı veriyi taşır.
| Aday | preload yok | resmî | classmap | En iyi kazanç | fpm bedeli |
|---|---|---|---|---|---|
| Laravel | 76,31 ms | yok | 13,98 ms | 5,5× | +2.340 ms |
| Symfony en büyük kazanç | 35,58 ms | 2,50 ms | kırıldı | 14,2× | −40 ms |
| Laminas | 26,70 ms | yok | 3,81 ms | 7,0× | −7 ms |
| CodeIgniter | 20,75 ms | 3,13 ms | 5,29 ms | 6,6× | −12 ms |
| Yii2 | 16,98 ms | yok | 4,80 ms | 3,5× | +13 ms |
| Slim | 7,46 ms | yok | 1,86 ms | 4,0× | +28 ms |
| Phalcon sınıfları C eklentisinde | 2,68 ms | yok | 1,99 ms | 1,3× | +43 ms |
Ayak izi kaydının otuz üç kat farkı preload’la kapanıyor: Symfony 2,50 ms’ye, yani Phalcon’un çıplak seviyesine iniyor. Fark framework’ün ağırlığından değil, opcache’in soğuk olmasından geliyormuş.
Ama beşinde yok
| Aday | Resmî preload | Nerede |
|---|---|---|
| Symfony | var | var/cache/prod/*.preload.php (warm-up üretiyor) |
| CodeIgniter | var | preload.php (başlangıç şablonunda) |
| Laravel | yok | — |
| Yii2 | yok | — |
| Laminas | yok | — |
| Slim | yok | — |
| Phalcon | yok | gerekmiyor |
Tablonun ikinci sütunu birinci sütundan daha çok şey söylüyor. Kazanç var ama beş adayda kullanıcının kendi yazmasını bekliyor — ve en çok kazanacak olan Laravel (76,31 ms) tam da o beşin içinde.
”Hepsini derle” doğru cevap değil
Resmî dosyası olmayan framework için akla gelen ilk çözüm şu: Composer zaten bütün sınıfları biliyor, classmap’i gezip hepsini derle. Ölçüm bunu iki farklı biçimde çürütüyor.
Symfony’de konteyner hiç ayağa kalkmıyor. 4.721 dosyayı yükleme anında derlemek, env değişkeni çözen sınıflara çarpıyor:
NOTICE: PHP message: [critical] Uncaught Exception:
Environment variable not found: "DEFAULT_URI".
Preload php-fpm’in master sürecinde koşuyor; orada ölen bir şey servisi hiç
başlatmıyor. Ölçüm bunu ready: false diye kaydediyor.
CodeIgniter’da daha kötü sonuç veriyor. Resmî dosya 3,13 ms, classmap 5,29 ms. Elle seçilmiş kırk küsur sınıf, körlemesine derlenmiş 479 dosyadan iyi. Preload paylaşılan belleği dolduruyor ve gereksiz sınıflar yer kaplıyor.
Bedel kaybolmuyor, yer değiştiriyor
Preload derleme işini isteğin içinden alıp php-fpm’in açılışına taşıyor. Küçük preload’larda bu bedel ölçülemiyor; büyük olanda çok net:
| Aday | Derlenen dosya | fpm hazır olma süresi | Fark |
|---|---|---|---|
| Laravel her deploy bunu ödüyor | 4.721 | 2.755 ms | +2.340 ms |
| Laminas | 1.195 | 352 ms | −7 ms |
| Yii2 | 992 | 352 ms | +13 ms |
| CodeIgniter | 479 | 324 ms | −12 ms |
| Slim | 138 | 359 ms | +28 ms |
| Phalcon | 3 | 362 ms | +43 ms |
Laravel’in classmap preload’ı her ziyaretçiden 62 ms alıp deploy’a 2,3 saniye yazıyor. Sürekli trafiği olan bir serviste bu iyi bir takas — ilk ziyaretçi bir kez ödüyor, sonrakiler hiç. Günde on kez deploy eden bir serviste ise takas tersine dönüyor: yirmi üç saniyelik açılış gecikmesi karşılığında birkaç yüz ziyaretçinin 62 ms’si.
Phalcon negatif kontrol oldu
Phalcon’un classmap’inden yalnız 3 dosya derlendi — sınıfları PHP’de değil C eklentisinde. Kazanç da en düşük: 1,3×. Bu, ölçümün ne ölçtüğünü doğrulayan kontrol: preload PHP kaynak derlemesini siliyorsa, derlenecek PHP kaynağı olmayan adayda etkisiz olmalı. Öyle oldu.
Ayak izi kaydına geri dönüş
O kayıt “disk boyutu hiçbir şey öngörmüyor, gerçekten ayrışan tek şey opcache soğukken ödenen ilk istek” demişti. Bu ölçüm o cümleye bir şart ekliyor: opcache soğuk kalmak zorunda değil — ama kalmaması, framework’ünüzün size bir preload dosyası verip vermemesine bağlı.
İlgili yazılar
2026'da PHP ile uygulama geliştirmek: ekosistemin hali
PHP'nin 2026'daki gerçek durumu: dil olgunluğu, ekosistem sağlığı ve 'öldü' söyleminin neden hâlâ yanlış olduğu.
PHP Öldü mü? 2026 Tablosu, Veriyle
18 yıllık bir PHP geliştiricisinin gözünden — W3Techs, Stack Overflow, JetBrains ve Packagist verileriyle PHP'nin 2026 fotoğrafı, ve dilin görmezden gelinen zayıflıkları.