RoadRunner — Persistent PHP Worker
debt(d8/e7/b7/t7)
Closest to 'silent in production until users hit it' (d9), slightly better at d8 because Blackfire profiling and memory growth monitoring can surface leaks, but state-bleed bugs between requests typically only manifest under production load with no automated detection.
Closest to 'cross-cutting refactor across the codebase' (e7), because adopting RoadRunner requires auditing every static property, service container reset, DB connection handling, and singleton across the entire app — not a localized change despite the simple composer require.
Closest to 'strong gravitational pull' (b7), because once on RoadRunner every new feature must be written with awareness of request-to-request state persistence; it shapes how services, caches, and singletons are designed across web/cli/queue contexts.
Closest to 'serious trap' (t7), because the misconception explicitly states devs assume it's a drop-in PHP-FPM replacement — it contradicts PHP's foundational shared-nothing per-request model that every PHP dev internalizes.
Also Known As
TL;DR
Explanation
RoadRunner manages long-lived PHP workers that bootstrap once (load framework, DI container) and handle multiple requests sequentially. Benefits: eliminates 20-50ms Laravel bootstrap, lower memory per request, WebSocket and gRPC support. Requires stateless PHP code with explicit state reset between requests.
Common Misconception
Why It Matters
Common Mistakes
- Static properties accumulating between requests
- DB connections not re-validated
- Not resetting service container
- Memory leaks killing workers
Code Examples
// FPM: 45ms bootstrap on every request
// 1000 requests = 45s in bootstrap alone
while ($request = $worker->waitRequest()) {
$app->resetState();
$worker->respond($app->handle($request));
}