Model eksekusi PHP klasik
Sebelum memilih FrankenPHP atau RoadRunner, kamu perlu tahu persis biaya apa yang sedang kamu hilangkan. Model "share-nothing" PHP adalah kekuatan sekaligus pemborosan — dan keduanya berasal dari fakta yang sama.
Intisari
- PHP-FPM: satu permintaan = satu proses pekerja yang membangun ulang seluruh aplikasi, lalu membuang semuanya.
- Keuntungannya: tidak ada kebocoran memori yang bisa bertahan, dan tidak ada state yang bocor antar pengguna.
- Biayanya: bootstrap Laravel (autoload, provider, konfigurasi, rute) dibayar berulang-ulang, selamanya.
- Worker mode membalik pertukaran ini: bootstrap sekali, lalu jaga sendiri kebersihan state-nya.
- Yang tidak diperbaiki worker mode: query lambat, N+1, dan panggilan API yang lambat.
Bagaimana PHP-FPM bekerja
permintaan → Nginx → FPM memilih proses pekerja yang menganggur
├─ muat autoloader Composer
├─ bangun Application, jalankan bootstrap/app.php
├─ register lalu boot SEMUA service provider
├─ muat konfigurasi, muat rute
├─ jalankan middleware → controller
├─ kirim respons
└─ BUANG SELURUH MEMORI PROSES
Baris terakhir itu adalah inti model share-nothing PHP. Setiap permintaan mulai dari nol dan berakhir tanpa jejak. Tidak ada objek yang bertahan, tidak ada variabel statis yang menumpuk, tidak ada koneksi yang tertinggal terbuka.
| Sifat | Akibat baiknya | Akibat buruknya |
|---|---|---|
| Memori dibuang tiap permintaan | Kebocoran memori tidak mungkin menumpuk | Semua yang mahal dibangun ulang |
| Tidak ada state bersama | Data pengguna tidak bisa bocor ke pengguna lain | Cache dalam proses tidak ada gunanya |
| Proses mati setelah selesai | Bug yang merusak state cuma merusak satu permintaan | Koneksi database dibuka ulang terus |
| Kode dibaca ulang | Deploy = ganti berkas, selesai | Perlu OPcache supaya tidak diurai ulang |
Berapa biayanya sebenarnya
// routes/web.php
Route::get('/ukur', fn () => [
'bootstrap_ms' => round((microtime(true) - LARAVEL_START) * 1000, 2),
'memori_mb' => round(memory_get_peak_usage(true) / 1048576, 1),
'berkas' => count(get_included_files()),
]);
Pada aplikasi Laravel berukuran sedang dengan OPcache aktif, angka bootstrap_ms biasanya berada di
kisaran belasan hingga puluhan milidetik, dengan ribuan berkas yang harus disatukan. Angka itu dibayar
setiap permintaan — bahkan untuk halaman yang seluruh isinya datang dari cache.
Ukur milikmu sendiri, jangan pakai angka orang lain. Biaya bootstrap sangat bergantung pada jumlah paket yang terpasang. Aplikasi dengan tiga puluh service provider dari paket pihak ketiga membayar jauh lebih banyak daripada aplikasi polos — dan justru aplikasi seperti itulah yang paling diuntungkan worker mode.
Apa yang berubah di worker mode
SAAT PROSES MENYALA (sekali saja)
├─ muat autoloader
├─ bangun Application
└─ register + boot semua provider
UNTUK SETIAP PERMINTAAN
├─ buat objek Request baru
├─ jalankan middleware → controller
├─ kirim respons
└─ RESET state framework — lalu tunggu permintaan berikutnya
| PHP-FPM | Worker mode | |
|---|---|---|
| Bootstrap framework | Tiap permintaan | Sekali per proses |
| Koneksi database | Dibuka ulang (kecuali persistent) | Dipakai ulang |
| Variabel statis | Selalu bersih | Bertahan — bisa jadi bug |
| Kebocoran memori | Tidak mungkin bertahan | Menumpuk sampai worker di-restart |
| Deploy | Ganti berkas | Wajib restart proses |
| Cache dalam proses | Sia-sia | Sangat efektif |
Apa yang tidak diperbaiki worker mode
| Masalah | Membaik? | Obatnya |
|---|---|---|
| Query N+1 | Tidak | Eager loading (Fase 2) |
| Query tanpa index | Tidak | Index (Fase 7) |
| API pihak ketiga yang lambat | Tidak | Antrean, cache, timeout |
| Halaman yang mengirim 2 MB HTML | Tidak | Paginasi, kurangi isinya |
| Biaya bootstrap framework | Ya, hampir hilang | Inilah yang dibeli worker mode |
| Membangun objek berat tiap permintaan | Ya | Singleton kini benar-benar bertahan |
Ini urutan yang benar, dan sering dibalik orang. Kalau permintaanmu menghabiskan 400 ms — 30 ms bootstrap dan 350 ms query — worker mode memangkasnya jadi sekitar 370 ms. Perbaikan 7%, dengan tambahan seluruh kelas bug state yang baru. Perbaiki query-nya dulu; setelah permintaan tinggal 40 ms, barulah 30 ms bootstrap menjadi bagian terbesar yang tersisa — dan di titik itu worker mode memberi perbaikan yang dramatis.
Jalur yang tersedia
| Runtime | Model | Bahasa penulisnya |
|---|---|---|
| PHP-FPM | Proses per permintaan | C (bagian dari PHP) |
| FrankenPHP | PHP tertanam di dalam web server; utas per permintaan | Go |
| RoadRunner | Server Go + kumpulan proses PHP CLI | Go |
| Swoole | Ekstensi PHP dengan event loop dan coroutine | C++ |
Tiga yang terakhir semuanya didukung Laravel Octane, yang menyediakan satu antarmuka di atasnya. Materi berikutnya membahas Octane; setelah itu kita masuk ke FrankenPHP dan RoadRunner satu per satu, lalu membandingkannya.
Latihan: pasang rute /ukur di atas, jalankan dengan PHP-FPM atau
php artisan serve, dan catat ketiga angkanya. Simpan — angka ini adalah pembanding untuk setiap
materi berikutnya di fase ini.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.