mrkeyoor.com_
Sat 24 Oct 07:22 UTC
Webevaluationupdated 24 Oct 2026

frankenphp review

FrankenPHP is a PHP application server built on Caddy, combining PHP execution with web serving and automatic HTTPS. Its optional worker mode keeps your application loaded between requests. That avoids repeating application startup but requires deliberate handling of request-specific state.

Verdict

FrankenPHP merits an application-specific trial when combining Caddy and PHP addresses an operating need. Check required extensions, request-state cleanup and server restart arrangements, including the documented hard-memory-limit shutdown risk. Our repository build command passed, while the test command failed with unexplained package build failures. Their applicability to your environment remains unresolved; this run establishes neither application correctness nor a performance gain.

We ran it

Lab card: what happened when we ran frankenphpScreenshot of frankenphp (frankenphp.dev)
Install✓ · 40s92 packages
Build✓ · 32s
Tests✗ · 12s3 passed · 5 failed of 8 (go test)
Repo605 files~40,839 lines of source · 6.4 MB · 12 CI workflows · Dockerfile · tests dir

Answers from our run

Does frankenphp build from source?

Dependencies installed in 40 seconds (92 packages), and the build succeeded in 32 seconds. We cloned commit 3b6ef0f into a clean Debian container with 3 CPUs and no project-specific setup.

Do frankenphp's tests pass?

No. The project's own test command finished in 12 seconds and reported 3 passed, 5 failed (go test).

Who should not use frankenphp?

Applications that must retain imap, newrelic or pcov unchanged: the known-issues page lists these extensions as incompatible because they are not thread-safe.

What are the alternatives to frankenphp?

PHP-FPM, RoadRunner. FrankenPHP merits an application-specific trial when combining Caddy and PHP addresses an operating need.

SetupN/AInstallation and the repository build command passed, but a packaged deployment serving a real PHP application was not reproduced.
Docs4/5On the visible rubric, 4 means clear guidance with explicit operating limits but deployment validation outstanding. The supplied guides explain persistent state, incompatible extensions and hard-memory-limit shutdown with restart mitigation. A packaged application deployment was not validated.
CommunityN/AGitHub API metadata observed on October 24, 2026 records lastPush as 2026-10-23T19:17:05Z. Maintainer responsiveness and community support were not assessed.
MaturityN/AThe package build failures lack compiler diagnostics, and the run did not measure application serving, worker isolation or production reliability.

Who it’s for

PHP teams evaluating combined application execution, web serving and HTTPS.
Symfony or Laravel Octane teams prepared to inspect their stateful services and documented worker integrations.
Developers embedding PHP in a Go application through net/http.
Operators who can validate required extensions, repeated-request behavior and server restart arrangements before migrating.

Who it’s NOT for

Applications that must retain imap, newrelic or pcov unchanged: the known-issues page lists these extensions as incompatible because they are not thread-safe.
Teams expecting worker mode to reset all application state automatically: static properties, globals and changes to $_ENV can survive requests.
Deployments requiring GLOB_BRACE in the documented musl-based binaries or Alpine images.
Deployments that cannot accommodate the documented whole-server shutdown risk when PHP's hard memory limit is exceeded.

Setup reality

Our October 23, 2026 run at commit 3b6ef0f recorded 92 dependencies during installation, which succeeded in 40 seconds. The repository build command passed in 32 seconds. The test command exited with code 1 after 12 seconds, with 3 passing and 5 failing package results. The failures were labelled build failed; the supplied log tail omits the compiler diagnostics needed to explain them. Their cause and applicability to the reader's environment remain unresolved.

The README documents standalone binaries and Docker images. These deployment routes still require your application, configuration and required PHP extensions. Worker mode also needs a worker script or framework integration. We did not reproduce a packaged deployment serving a PHP application.

The source-compilation guide requires a compatible PHP library with thread safety enabled. The recorded sandbox image was golang:1.24-bookworm, but that label does not establish the actual Go, PHP or operating-system versions.

FrankenPHP worker mode keeps your application in memory between requests. A migration trial should check retained user state, required PHP extensions and what happens when the server process stops. Our repository run supplies build and package-check results, but it does not establish application correctness or a performance gain.

What FrankenPHP combines

The FrankenPHP README describes a PHP application server built on Caddy, with automatic HTTPS. It can also embed PHP in a Go application using net/http.

Worker mode is optional. The documentation describes Symfony and Laravel Octane integrations and a custom worker-script route. Keeping the application bootstrapped avoids repeating startup for each request. Whether that benefit justifies migration needs an application workload, which our measurements do not include.

What happened when we ran it

At commit 3b6ef0f on October 23, 2026, installation succeeded in 40 seconds and recorded 92 dependencies. The repository build command passed in 32 seconds. The test command failed after 12 seconds with exit code 1.

The sandbox configuration recorded 3 CPUs, 8 GB of RAM and the image label golang:1.24-bookworm. The checkout contained 605 files, approximately 40,839 source lines and 6.4 MB of data. The image label does not establish actual runtime or operating-system versions.

The Go summary contains 3 passing and 5 failing package results. The passing packages were internal/extgen, internal/phpheaders and internal/state. The root package, internal/testcli, internal/testext, internal/testserver and internal/watcher were marked build failed. These are package outcomes, not eight individual behavior tests.

The supplied tail lacks the compiler diagnostics behind those failures. Their cause and applicability to another environment remain unresolved. The log does not establish a missing dependency, incompatible PHP version or watcher-library problem. The successful repository build command also does not establish that a runnable server binary was produced or that a PHP application served requests correctly. The scan found 12 CI workflow files, a Dockerfile and a tests directory; their presence does not change the failed local test result.

State can outlive a request

The worker guide documents static variables, class static properties and globals persisting between requests. Arrays and objects outside the request handler persist too. A service that retains the current user's details therefore needs deliberate cleanup.

Most request superglobals reset between requests, but $_ENV does not. Changes to the working directory, default stream context and other documented runtime settings also persist. Symfony and Laravel Octane reset much of their own state, but the guide warns that applications may still need to reset their own services.

Before migrating, list services that store request-specific data. A useful application check is to alternate requests from different users through the same worker and inspect retained state. This is a proposed validation step, not a sandbox result. Monitor memory over repeated requests as well: the guide describes restarting workers after a configured request limit as a workaround for libraries that leak memory.

A hard memory limit can stop the whole server

The known-issues page documents a separate process-level risk. Since PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12, exceeding memory_limit raises the fatal error at the next function call or loop iteration rather than stopping the script immediately. If allocations reach PHP's hard memory limit before that, PHP exits the process.

FrankenPHP serves all requests from threads of a single process, so every in-flight request is lost and the server stops until it is restarted. The documentation recommends a supervisor that restarts FrankenPHP, such as a Docker restart policy or systemd's Restart= setting, which it says is already set in the deb and rpm packages.

This is a documented operating risk, not a failure observed in our sandbox. Restarting workers after a request limit addresses the worker guide's memory-leak scenario; deployment planning must also account for a server process exiting at the hard memory limit. Check the PHP version and restart configuration in the deployment you intend to use. The sandbox image label does not establish which PHP version ran.

Check extensions and distribution compatibility

The known-issues page lists imap, newrelic and pcov as incompatible because they are not thread-safe. If your application requires one unchanged, that is a reason to retain another serving path.

The same page says the documented musl-based static binary and Alpine Docker images lack GLOB_BRACE. It recommends the GNU binary variant or Debian-based images when compatibility issues arise. For the README's local Docker HTTPS example, use localhost rather than 127.0.0.1. These documented limits do not establish the cause of our package build failures.

Choose a deployment route before interpreting the build

The README offers standalone binaries and Docker images. The source-compilation guide describes building with a compatible PHP library and thread safety enabled. A passing repository build command does not replace deployment checks for your application, extensions and configuration.

Documentation receives 4/5 on this review's scale: 1 means unusable instructions, 3 means useful guidance requiring reconciliation, 4 means clear guidance with explicit operating limits but deployment validation still outstanding, and 5 requires consistent coverage confirmed through the relevant deployment checks. The supplied guides explain persistent state, identify incompatible extensions and describe the hard-memory-limit shutdown risk with restart mitigation. We did not validate a packaged application deployment, so the assessment stops at 4.

The supplied GitHub API metadata, observed on October 24, 2026, records the repository's last push as October 23, 2026 at 19:17:05 UTC. Maintainer responsiveness and community support were not assessed; a push timestamp does not establish either.

Alternatives depend on the operating model

PHP-FPM is PHP's FastCGI process manager with configurable worker pools. Consider it when you want to retain a separate FastCGI deployment and its pool controls.

RoadRunner is a PHP application server and process manager written in Go and extended through plugins. Consider it when that plugin model fits the service you need to operate. We measured neither alternative.

For a FrankenPHP trial, start with an extension inventory and a list of services holding request-specific state. Check server restart arrangements, then validate repeated requests in the deployment route you intend to use. Our repository build command passed, but the failed package checks remain unexplained and application behavior remains unmeasured.

Alternatives

ProjectWhat it isPick it when
PHP-FPM gh↗PHP's FastCGI process manager, with configurable worker pools.Choose it when you want to retain a separate FastCGI deployment and its process-pool controls.
RoadRunnerA PHP application server and process manager written in Go and extended through plugins.Choose it when its plugin model matches the service you need to operate; no comparative performance measurement was supplied.

What people are saying

  1. [github-trending] php/frankenphp

Sources

  1. FrankenPHP README
  2. FrankenPHP worker mode
  3. FrankenPHP known issues
  4. PHP FastCGI Process Manager
  5. RoadRunner README
  6. Compile FrankenPHP from sources

More web reviews

jiangshan-map · ziwei-doushu · Leaflet · react-virtualized · emdash · dioramas · the whole board →