{
    "slug": "php_roadrunner",
    "term": "RoadRunner — Persistent PHP Worker",
    "category": "performance",
    "difficulty": "advanced",
    "short": "Go-based server keeping PHP workers alive between requests — eliminating per-request bootstrap cost.",
    "long": "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.",
    "aliases": [
        "RoadRunner",
        "persistent PHP",
        "PHP worker pool"
    ],
    "tags": [
        "performance",
        "php",
        "devops"
    ],
    "misconception": "RoadRunner is a drop-in PHP-FPM replacement — it requires significant changes to handle stateful objects between requests.",
    "why_it_matters": "RoadRunner changes PHP's execution model fundamentally — instead of spinning up a fresh PHP process for every request, workers persist and handle multiple requests in sequence. This eliminates bootstrap overhead for frameworks like Laravel and Symfony, which can shave 50–150ms per request. The trade-off is that state must be explicitly reset between requests — static variables, service container state, and in-memory caches persist across requests unless reset, which is a common source of subtle bugs during migration.",
    "common_mistakes": [
        "Static properties accumulating between requests",
        "DB connections not re-validated",
        "Not resetting service container",
        "Memory leaks killing workers"
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "swoole_openswoole",
        "php_concurrency_options",
        "php_async_frameworks"
    ],
    "prerequisites": [
        "php_async_frameworks",
        "php_fpm",
        "php_concurrency_options"
    ],
    "refs": [
        "https://roadrunner.dev/docs"
    ],
    "bad_code": "// FPM: 45ms bootstrap on every request\n// 1000 requests = 45s in bootstrap alone",
    "good_code": "while ($request = $worker->waitRequest()) {\n    $app->resetState();\n    $worker->respond($app->handle($request));\n}",
    "quick_fix": "Add RoadRunner to your PHP app with composer require spiral/roadrunner — it keeps PHP workers alive between requests eliminating bootstrap cost, giving 3-5x throughput improvement",
    "severity": "medium",
    "effort": "high",
    "created": "2026-03-16",
    "updated": "2026-03-23",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/php_roadrunner",
        "html_url": "https://codeclaritylab.com/glossary/php_roadrunner",
        "json_url": "https://codeclaritylab.com/glossary/php_roadrunner.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[RoadRunner — Persistent PHP Worker](https://codeclaritylab.com/glossary/php_roadrunner) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/php_roadrunner"
            }
        }
    }
}