Mengganti model eksekusi tradisional dengan worker mode: memahami perbedaan PHP-FPM vs aplikasi yang hidup permanen, menjalankan Symfony dengan FrankenPHP dan RoadRunner, serta kapan memilih yang mana untuk production.

Selama 21 episode, aplikasi berjalan dengan model eksekusi klasik PHP: proses di-spawn per request (FPM). Episode 22 memperkenalkan model baru yang sedang naik daun di 2026: worker mode — aplikasi yang di-load sekali dan hidup terus, melayani banyak request.
Mengapa ini penting? Karena biaya terbesar request bukan kode-nya, melainkan bootstrap — inisialisasi container, load autoloader, build metadata. Worker mode membayar biaya itu sekali saja. Hasilnya: peningkatan performa yang signifikan tanpa menambah server, dan itu alasan utama ekosistem PHP bergerak ke arah ini.
Setiap request mem-bootstrap seluruh aplikasi: container, autoload, metadata. Konsisten dan aman (state tidak bocor antar request), tapi boros untuk beban tinggi.
Aplikasi di-load sekali; request berikutnya tinggal diproses. Bootstrap tidak berulang — inilah sumber kecepatannya.
Symfony Runtime adalah abstraksi yang membuat aplikasi bisa dijalankan di berbagai model eksekusi tanpa mengubah kode:
composer require symfony/runtimeDengan runtime terpasang, public/index.php meminta runtime memilih runtime yang aktif. Kode aplikasi tidak berubah — hanya cara menjalankannya yang berbeda. Inilah yang membuat migrasi ke worker mode semulus mungkin.
FrankenPHP adalah app server PHP yang menanamkan PHP langsung di Caddy (Go). Menariknya: ia memakai model worker dengan cara yang automatic:
composer require frankenphp/symfony-runtimeKode (dengan PHP 8.4+ dan APP_RUNTIME=Runtime\\FrankenPHPRuntime) mengenali variabel environment FrankenPHP dan otomatis masuk worker mode:
APP_RUNTIME=Runtime\FrankenPHPRuntime
FRANKENPHP_WORKER=1Run via image resmi:
docker run -v .:/app -p 8080:80 dunglas/frankenphp:8.4Keunggulan FrankenPHP:
| Aspek | Nilai |
|---|---|
| Setup | composer require + env var — tanpa konfigurasi worker manual |
| HTTPS | Bawaan Caddy (auto Let's Encrypt) |
| Tambahan | Dukungan WebSocket, Mercure, HTTP/3 |
| Integrasi | Resmi didukung Symfony (Symfony Runtime) |
Untuk memaksimalkan cache opcode dalam mode worker, hindari opcache.validate_timestamps di dev — di production, set 0 (seperti episode 14).
RoadRunner (ditulis Go oleh Spiral) adalah pendekatan berbeda: server Go memakai PHP sebagai worker dalam sub-proses:
composer require spiral/roadrunner-cli
composer require spiral/roadrunner-symfony
vendor/bin/rr getKonfigurasi .rr.yaml:
server:
command: "php worker.php"
http:
address: ":8080"
pool:
num_workers: 8worker.php adalah entri point standar:
use Symfony\Component\Runtime\SymfonyRuntime;
use Symfony\Component\HttpKernel\KernelInterface;
require_once dirname(__DIR__) . '/vendor/autoload_runtime.php';
return function (array $context): KernelInterface {
$kernel = new App\Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
return $kernel;
};Lalu:
./rr serveKeunggulan RoadRunner:
| Aspek | Nilai |
|---|---|
| Pool management | num_workers eksplisit, restart otomatis |
| Ekosistem | Memori & lifecycle worker terkontrol penuh |
| Tambahan | GRPC, jobs (queue), KV (Redis) terintegrasi |
| Faktor | FrankenPHP | RoadRunner |
|---|---|---|
| Kemudahan setup | Sangat mudah (1 command) | Sedang (file .rr + worker) |
| Kontrol worker | Otomatis | Manual (num_workers) |
| Fitur tambahan | HTTPS, WebSocket, Mercure | GRPC, jobs, KV |
| Paling cocok | Symfony murni, cepat jalan | Platform dengan banyak kebutuhan non-HTTP |
Tip
Aturan praktis: mulai dari FrankenPHP jika kalian murni membutuhkan HTTP cepat dan otomatis. Pilih RoadRunner jika project membutuhkan GRPC, job queue, atau kontrol pool yang presisi. Keduanya bisa hidup berdampingan — lihat episode 23 untuk packaging Docker-nya.
Worker mode bukan hanya untuk HTTP — ia berpasangan sempurna dengan Messenger (episode 10): worker yang sama bisa melayani HTTP dan mengkonsumsi antrian. Dengan RoadRunner misalnya, eksekutor HTTP dan jobs diatur dalam satu server:
http:
address: ":8080"
jobs:
consume:
- "app.queue"Ini menyederhanakan operasional: satu proses, satu health check, satu unit scaling.
reset() atau state per-request dibersihkan di akhir request (Symfony Runtime menangani ini).cache:clear/restart worker saat deploy.Pada episode 22 ini, kalian telah memahami dan menjalankan worker mode.
Inti yang harus dibawa pulang:
Di episode 23 selanjutnya kita mempackaging semuanya: Docker & Deployment CI/CD — Dockerfile multi-stage, compose untuk dev/prod, migrasi & cache warmup saat deploy, dan pipeline GitHub Actions. Sampai jumpa di episode 23!