# Laravel Octane (FrankenPHP) altında bellek sızıntısını nasıl debug ederim?

> Önce memory_get_usage eğrisini çıkarın, service provider'ları bisect edip suçluyu daraltın, stateful singleton'ları Octane hook'larında sıfırlayın.

- Soruldu: 2026-05-13
- Yanıtlandı: 2026-05-16
- Soran: Yiğit
- Etiketler: performans, laravel, octane
- Kaynak: https://muhammetsafak.com/tr/sor-bakalim/laravel-octane-frankenphp-bellek-sizintisi-nasil-debug-edilir/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Laravel Octane'i FrankenPHP sürücüsüyle `max-requests=500` ile çalıştırıyoruz. Yüksek trafikte worker'ların bellek tüketimi hızla artıyor, RAM şişip sunucu kilitlenme noktasına geliyor.

PHP-FPM'de her istek sonrası bellek temizlenirken Octane'in durumsal yapısında singleton'lar, static değişkenler ve third-party paketlerin yol açtığı bu sızıntıyı nasıl debug ederim? Worker'ları kalıcı tutarken belleği nasıl optimize ederim?


Kısa cevap: Tahmin etmeyin, **ölçün** — Octane'de worker uzun ömürlü olduğu için istekler arasında biriken her şey sızar; önce neyin biriktiğini izleyip yakalayın, sonra stateful tarafı hook'larda sıfırlayın.

## Kısa cevap

Asıl mesele şu: PHP-FPM "her istekte taze süreç" varsayar, Octane ise worker'ı ayakta tutar. Bu varsayımı bozan her şey — büyüyen static array'ler, request state tutan singleton'lar, her istekte yeniden register edilen listener/binding'ler ve Octane'in bilmediği her durum — sessizce belleği şişirir. Octane kendi framework durumunu istekler arasında sıfırlar (auth guard'ları, log bağlamı, request örneği); görmediği durumu sıfırlamak sizin işiniz. Kalıcı sürecin bu modeli neyi değiştirdiğini [Laravel Octane yazısında](/tr/blog/laravel-octane-kalici-surecle-gelen-performans/) anlatmıştım.

## Neden

1. **Sızıntı bir kod hatası değil, bir varsayım ihlali.** PHP-FPM'de her istek kendi sürecinde doğup ölüyordu; sızdıran kod da onunla birlikte ölüyordu. Octane bu güvenlik ağını kaldırıyor, aynı kod aynı sürecde biriktirmeye başlıyor.

2. **Suçlu çoğu zaman kendi kodunuz değil.** "Her istekte taze süreç" varsayan bir third-party paket PHP-FPM'de görünmez, Octane'de patlar. Bu yüzden okuma değil ölçüm gerekiyor.

3. **`--max-requests` kök nedeni gizler.** Worker'ı belli sayıda istekten sonra geri dönüştürmek RAM'i sınırlar ama sızıntıyı kapatmaz — `500`'ü düşürmek sizi sadece geç çökmeye taşır.

## Ne yapmalı

1. **Önce ölçün, sonra konuşun.** Her N istekte bir `memory_get_usage(true)`'yi loglayın; bellek monoton artıyorsa sızıntı vardır, dalgalanıp düşüyorsa normaldir. Octane'in `RequestTerminated` hook'una bir sayaç koyun ve eğrinin şeklini görün.

2. **Bisect ile suçluyu bulun.** Service provider'ları ve şüpheli paketleri tek tek devre dışı bırakıp eğriyi tekrar ölçün; artış nerede duruyorsa sızıntı oradadır. Snapshot diff'i (iki noktada `memory_get_usage` farkı) hangi tipin biriktiğini daraltır.

3. **Stateful singleton'ları hook'ta sıfırlayın.** Request state tutan binding'leri `RequestReceived`/`RequestTerminated` hook'larında ya da `config/octane.php` içindeki `flush` listesiyle temizleyin. Singleton'ı container'da bırakıp içindeki state'i resetlemek, çoğu sızıntıyı tek satırda kapatır.

4. **Static birikimi öldürün, servisi request başına yeniden bağlayın.** Büyüyen static `$cache = []` array'leri, kapanmayan bağlantılar, istek başına şişen koleksiyonlar tipiktir. Request scope'una ait servisi singleton yapmayın; her istekte yeniden bind edin ki taşıdığı veri istekle birlikte ölsün.

5. **`--max-requests`'i emniyet supabı olarak açık tutun.** Ama asıl işi sızıntıyı kapatarak yapın; ona bel bağlamayın.

**Sonuç:** Ben olsam sırayı şöyle kurardım: önce `memory_get_usage` ile eğriyi çıkarın, sonra service provider/paketleri bisect ederek suçluyu daraltın, ardından stateful singleton'ları Octane hook'larında sıfırlayın ve static birikimi temizleyin. `--max-requests`'i bir güvenlik ağı olarak elinizde tutun ama ona bel bağlamayın. Octane'in hızını alacaksanız, "süreç her istekte ölmüyor" gerçeğini kodun her katmanında kabul etmeniz gerekir.

## İlgili Yazılar

- [Laravel Octane: kalıcı süreçle gelen performans](/tr/blog/laravel-octane-kalici-surecle-gelen-performans/) — Blog
- [İşlediğim satırları aynı anda güncellerken chunk yerine chunkById mı kullanmalıyım?](https://muhammetsafak.com/tr/sor-bakalim/isledigim-satirlari-ayni-anda-guncellerken-chunk-yerine-chunkbyid-mi-kullanmaliyim/) — Sor Bakalım
- [Eloquent'te N+1'i erken yakalamak için Model::preventLazyLoading'i yalnızca lokalde mi yoksa production'da da mı açmalıyım?](https://muhammetsafak.com/tr/sor-bakalim/eloquentte-n-1i-erken-yakalamak-icin-model-preventlazyloadingi-yalnizca-lokalde-mi/) — Sor Bakalım
- [2-5 GB dosyaları PHP belleğini şişirmeden stream ile nasıl indirtirim?](https://muhammetsafak.com/tr/sor-bakalim/buyuk-dosyalari-php-bellegini-sismeden-stream-ile-indirmek/) — Sor Bakalım
