For decades, PHP-FPM (FastCGI Process Manager) has been the undisputed heavyweight champion of running PHP in production, typically paired with web servers like Nginx or Apache. But a new contender has entered the arena: FrankenPHP, a modern application server written in Go that is changing the way we think about deploying PHP.
So, is it time to retire your reliable PHP-FPM setup? Let’s break down the classic FastCGI architecture versus the modern, all-in-one approach of FrankenPHP.
The Established King: PHP-FPM
PHP-FPM is a process manager that maintains a pool of PHP worker processes, ready to handle incoming requests.
How It Works
- A web server (e.g., Nginx) receives a request.
- It sends the request to the PHP-FPM process pool via the FastCGI protocol.
- An available FPM worker process takes the request.
- The PHP interpreter in the worker:
- Starts from scratch.
- Loads the PHP files (autoloader, framework, etc.).
- Handles the request and generates a response.
- The process is then ready for a new request (or is terminated).
Core insights
- Architectural Simplicity: It’s a proven, battle-tested model.
- Shared-Nothing: Each request generally starts clean, which offers excellent stability and memory isolation (a memory leak in one process won’t affect others).
- Overhead: The major drawback is the “bootstrapping” cost. For every single request, the PHP interpreter must load the entire framework (like Symfony or Laravel) and application code, which adds significant overhead and latency.
The Modern Challenger: FrankenPHP
FrankenPHP bills itself as “The Modern PHP App Server.” It’s built on the Caddy web server (written in Go) and embeds the PHP interpreter directly, eliminating the need for a separate FPM process and the FastCGI middleman.
Two Modes of Operation
FrankenPHP offers flexibility with two main modes:
- Classic Mode (FPM Drop-in):
- Acts as a drop-in replacement for Nginx + PHP-FPM.
- It handles requests individually, similar to FPM, but without the FastCGI communication overhead.
- Result: Generally offers performance similar to or slightly better than a highly optimized Nginx + PHP-FPM stack.
- Worker Mode (The Game Changer):
- The true innovative feature. It keeps the PHP application (like your Symfony or Laravel kernel) warm and alive in memory across multiple requests.
- Result: It avoids the costly framework bootstrapping on every request. This can lead to dramatic performance improvementsโoften 3x to 10x faster in terms of throughput and significantly lower latency under load, especially for heavy frameworks.
Key Advantages Over PHP-FPM
- Performance: Worker mode offers massive performance gains by reducing per-request overhead.
- Simplified Deployment: It runs as a single binary or container image that includes the web server (Caddy) and PHP runtime. This simplifies configuration and deployment significantly.
- Modern Features: Comes with built-in support for HTTP/2, HTTP/3, automatic HTTPS/SSL (via Caddy), 103 Early Hints, and a built-in Mercure Hub for real-time capabilities.
Quick Comparison Table
| Feature | PHP-FPM + Nginx | FrankenPHP (Classic Mode) | FrankenPHP (Worker Mode) |
| Architecture | Separate Web Server + PHP Process Pool | All-in-one (Caddy + Embedded PHP) | All-in-one (Caddy + Persistent PHP) |
| Request Handover | FastCGI Protocol (Overhead) | Direct (Minimal Overhead) | Direct (Minimal Overhead) |
| Framework Bootstrapping | Every Request | Every Request | Once (Kept in memory) |
| Performance | Good (with tuning) | Very Good | Excellent (Significantly faster) |
| Protocol Support | HTTP/1.1, HTTP/2 (via Nginx) | HTTP/1.1, HTTP/2, HTTP/3 | HTTP/1.1, HTTP/2, HTTP/3 |
| Complexity | Higher (two components to configure) | Low (Single Binary) | Low (Single Binary, but worker code adaptation needed) |
Should You Switch?
The decision depends on your application and its stage:
- New Projects & APIs: Start with FrankenPHP in Worker Mode. The performance benefits and simplified architecture make it the superior modern choice.
- Mid-sized Monoliths & Legacy Apps: Try FrankenPHP in Classic Mode. It offers a simple drop-in replacement that may grant you some benefits (like HTTP/3 and Caddy’s features) without major code changes.
- Huge Legacy Systems: Stick to PHP-FPM for now, as the stability and process isolation are well-understood. Migration to a worker-mode architecture would require careful planning for persistent state.
Real-world benchmark highlights
- One benchmark found that FrankenPHP in classic mode served ~15,000 requests per second vs PHP-FPM just under ~4,000 requests per second when both were running the same minimal PHP file under similar hardware. Medium
- Another test found that at idle, PHP-FPM consumed ~20-25 MB memory and <1% CPU; FrankenPHP classic used ~60 MB memory and ~1-3% CPU; FrankenPHP worker mode ~85 MB memory. Medium
- In a performance overview, FrankenPHP worker mode reportedly achieved over 10ร higher throughput than Nginx+PHP-FPM under high concurrency in some tests. DEV Community
- Deployment articles note that while PHP-FPM remains โsolid and proven,โ modern alternatives like FrankenPHP are compelling for developers who care about performance. DeployHQ
From a cost perspective (thinking USD/cloud spend): if your service handles large sustained volumes of requests, then a per-container or per-VM basis, FrankenPHP may let you handle more requests with less machinery. For smaller or intermittent loads, PHP-FPM might still make more cost sense because youโre not paying the โalways-loadedโ memory/process overhead of worker-mode.
Conclusion
FrankenPHP represents the next evolution of running PHP, allowing it to compete with application servers in other languages by enabling a persistent application state. While PHP-FPM remains a rock-solid, stable choice, the performance and simplicity offered by FrankenPHP’s Worker Mode are too compelling to ignore for modern, high-traffic applications.