Comparing PHP Application Servers: Performance, Scalability, and Modern Options

Devops & Infrastructure, Open Source, and PHP

Comparing PHP Application Servers: Performance, Scalability, and Modern Options

Choosing a PHP application server used to be simple: you ran PHP-FPM behind Nginx, or you used Apache with mod_php. That was it. Today, you have genuinely compelling alternatives -- FrankenPHP, RoadRunner, Swoole, and LiteSpeed -- each with different architectures, trade-offs, and deployment models.

This guide compares the major PHP application servers head-to-head, covering architecture, performance characteristics, and practical deployment considerations. Whether you're evaluating a PHP-FPM alternative or trying to decide between FrankenPHP and RoadRunner for a new project, you'll find the comparison you need here.

The Traditional Setup: PHP-FPM and Apache mod_php

Before comparing modern alternatives, it's worth understanding the baseline that most PHP applications still run on.

PHP-FPM with Nginx

PHP-FPM (FastCGI Process Manager) is the most widely deployed PHP runtime. Nginx handles HTTP requests and forwards PHP requests to a pool of FPM worker processes via the FastCGI protocol. Each request gets its own process, the script executes, and the process resets for the next request.

How it works:

Client → Nginx (static files, TLS, routing) → PHP-FPM (PHP execution) → Response

This shared-nothing architecture is PHP's defining characteristic. Every request starts with a clean slate -- no leaked state, no memory accumulation, no cross-request contamination. It's simple, predictable, and easy to debug.

Strengths:

  • Battle-tested across millions of production sites
  • Extensive documentation and community knowledge
  • Simple process model with predictable memory usage
  • Works with virtually every PHP application without modification
  • Easy horizontal scaling by adding more FPM workers or servers

Limitations:

  • Bootstrap overhead on every request (framework loading, config parsing, service container building)
  • No native HTTP/2 or HTTP/3 support at the PHP layer
  • No built-in WebSocket or long-lived connection support
  • Each worker handles one request at a time

Apache mod_php

Apache with mod_php embeds the PHP interpreter directly into the Apache process. It's the oldest deployment model and still common in shared hosting environments.

While simpler to configure initially, mod_php ties the PHP lifecycle to Apache's process model. This means PHP runs even for static file requests, consuming more memory. For most production workloads, PHP-FPM with Nginx offers better resource efficiency and separation of concerns.

Best for: Shared hosting, legacy applications where changing the server stack isn't practical, and .htaccess-dependent workflows.

FrankenPHP: The Modern Contender

FrankenPHP is a modern PHP application server built on top of Caddy, written in Go. It embeds PHP directly into the web server, eliminating the Nginx-to-FPM handoff entirely.

How it works:

Client → FrankenPHP (Caddy + embedded PHP) → Response

FrankenPHP's worker mode keeps your PHP application loaded in memory between requests, eliminating the bootstrap overhead that slows down traditional PHP-FPM setups. This is where the performance gains come from -- your framework, service container, and configuration are loaded once, not on every request.

Key features:

  • Native HTTP/2 and HTTP/3 support
  • Automatic TLS via Caddy's built-in ACME support
  • Worker mode for persistent application state
  • Early Hints (103) support for faster page rendering
  • Built-in Mercure hub for real-time capabilities
  • Official Symfony and Laravel integration

Strengths:

  • Significantly reduced request latency in worker mode (community benchmarks typically show 2-4x throughput improvement over PHP-FPM for framework-heavy applications)
  • Single binary deployment -- no separate web server, no FPM configuration
  • Modern protocol support out of the box
  • Active development with growing community adoption

Considerations:

  • Younger project with a smaller production track record than PHP-FPM
  • Worker mode requires your application to be free of memory leaks and global state issues
  • Debugging can be more complex due to the persistent process model
  • Go dependency for building from source

FrankenPHP vs PHP-FPM

This is the comparison most teams are evaluating right now. Here's how they stack up:

Aspect PHP-FPM (with Nginx) FrankenPHP
Architecture Separate web server + process manager Single integrated server
Request model Process-per-request (shared-nothing) Worker mode (persistent) or classic mode
Bootstrap overhead Every request Once (worker mode)
HTTP/2, HTTP/3 Nginx handles HTTP/2; no HTTP/3 in standard setups Native HTTP/2 and HTTP/3
TLS management Manual or certbot Automatic via Caddy
WebSockets Requires separate solution Supported via Mercure
Configuration nginx.conf + php-fpm.conf + pool configs Single Caddyfile or CLI flags
Maturity 15+ years in production Active since 2022
Community size Massive Growing rapidly
Deployment complexity Moderate (multiple components) Low (single binary)

When to choose PHP-FPM: You're running a stable application with no performance bottlenecks at the PHP layer, your team knows the Nginx/FPM stack well, or you need the broadest possible compatibility (shared hosting, legacy apps, WordPress multisite at scale).

When to choose FrankenPHP: You're starting a new project, your application's response time is dominated by framework bootstrap, you want HTTP/3 and automatic TLS without extra tooling, or you're building real-time features.

RoadRunner: The Go-Powered Worker Server

RoadRunner is a high-performance PHP application server written in Go. Like FrankenPHP's worker mode, it keeps your PHP application loaded in memory, but RoadRunner has been doing this since 2018 and has a more mature plugin ecosystem.

How it works:

Client → RoadRunner (Go HTTP server) → PHP Workers (persistent) → Response

RoadRunner manages a pool of long-lived PHP worker processes. Each worker loads your application once and handles many requests sequentially. The Go layer handles HTTP, load balancing, and additional services.

Key features:

  • Worker mode with persistent PHP processes
  • Built-in job queue system (Kafka, AMQP, SQS, Beanstalk support)
  • gRPC server support
  • Key-value storage, service bus, and metrics
  • Plugin architecture for extensibility
  • Temporal workflow integration

Strengths:

  • Mature worker implementation with years of production use
  • Rich plugin ecosystem beyond just HTTP serving
  • Strong gRPC support for microservice architectures
  • Excellent Spiral Framework integration, good Laravel and Symfony support

Considerations:

  • Requires .rr.yaml configuration
  • Your application must handle persistent state carefully (same as FrankenPHP worker mode)
  • Adds Go as a runtime dependency
  • Less community buzz than FrankenPHP despite being more mature

Swoole: The Async PHP Runtime

Swoole takes a fundamentally different approach. Rather than bolting a persistent worker onto PHP's traditional execution model, Swoole extends PHP itself with an asynchronous, event-driven runtime -- similar to what Node.js provides for JavaScript.

How it works:

Client → Swoole HTTP Server (PHP extension) → Coroutine-based Workers → Response

Swoole runs as a PHP extension (PECL install) and provides its own HTTP server, WebSocket server, and coroutine-based concurrency. A single Swoole worker can handle thousands of concurrent connections using cooperative multitasking.

Key features:

  • Coroutine-based async I/O (database queries, HTTP requests, file operations)
  • Built-in HTTP, WebSocket, TCP, and UDP servers
  • Connection pooling for databases and external services
  • Process management and task workers
  • Millisecond-precision timers

Strengths:

  • Highest potential throughput for I/O-bound workloads
  • True concurrency within a single worker process
  • Built-in connection pooling eliminates per-request connection overhead
  • Laravel Octane provides first-class Swoole integration

Considerations:

  • Steepest learning curve of all options -- async programming requires rethinking how you write PHP
  • Not all PHP libraries are coroutine-compatible (blocking I/O in a coroutine blocks the entire worker)
  • Debugging async code is harder than synchronous PHP
  • PECL extension installation can complicate deployment pipelines
  • Smaller Western community (project originated in China)

FrankenPHP vs RoadRunner vs Swoole

This is the three-way comparison developers evaluating modern PHP servers need. All three eliminate bootstrap overhead and keep your application resident in memory, but they differ significantly in scope and complexity.

Aspect FrankenPHP RoadRunner Swoole
Language Go (Caddy-based) Go C (PHP extension)
Concurrency model Workers (one request at a time per worker) Workers (one request at a time per worker) Coroutines (many concurrent requests per worker)
Installation Single binary or Docker Composer + binary PECL extension
HTTP/2, HTTP/3 Both native HTTP/2 supported HTTP/2 supported
WebSockets Via Mercure Via plugin Native
Job queues No (use external) Built-in (Kafka, AMQP, SQS) Built-in task workers
gRPC No Yes Yes
TLS Automatic (Caddy) Manual configuration Manual configuration
Framework support Symfony, Laravel Spiral, Laravel, Symfony Laravel Octane, Hyperf
Maturity ~3 years ~7 years ~8 years
Best for Simple deploys, HTTP/3, new projects Microservices, job queues, gRPC High-concurrency I/O-bound workloads

Choose FrankenPHP if you want the simplest deployment model with modern protocol support and don't need built-in job queues or gRPC.

Choose RoadRunner if you need a mature worker server with an integrated job queue, gRPC support, or you're building microservices.

Choose Swoole if your application is heavily I/O-bound (many database queries, external API calls per request) and you're willing to invest in learning async PHP patterns.

LiteSpeed and OpenLiteSpeed

LiteSpeed is a commercial web server with a drop-in Apache replacement and a built-in PHP handler (LSAPI). OpenLiteSpeed is its open-source counterpart.

LiteSpeed is particularly dominant in WordPress and shared hosting environments, where it provides significant performance improvements over Apache without requiring application changes.

Key features:

  • Drop-in Apache replacement (reads .htaccess files)
  • LSAPI -- a persistent PHP handler faster than FastCGI
  • Built-in page caching (LSCache) with WordPress plugin
  • HTTP/2 and HTTP/3 (QUIC) support
  • Anti-DDoS features and ModSecurity compatibility

Strengths:

  • Easiest migration path from Apache -- swap the server binary, keep your configs
  • LSCache provides dramatic performance improvements for WordPress (often 5-10x faster page loads)
  • Mature commercial product with enterprise support options
  • OpenLiteSpeed provides most benefits for free
  • Strong adoption in cPanel/WHM hosting environments

Considerations:

  • LiteSpeed Enterprise requires a commercial license
  • OpenLiteSpeed has a smaller feature set than the commercial version
  • Less flexible than Nginx for complex reverse proxy configurations
  • Primarily beneficial for WordPress and CMS-heavy workloads

Best for: WordPress sites, shared hosting migrations from Apache, teams that need HTTP/3 with minimal configuration changes, and hosting providers managing many sites.

Comparison Summary

Server Type Best For Complexity HTTP/3 Worker Mode Maturity
PHP-FPM + Nginx Traditional General PHP hosting Low Via Nginx config No Excellent
Apache mod_php Traditional Shared hosting, legacy apps Low No No Excellent
FrankenPHP Modern worker New projects, simple deploys Low Yes Yes Growing
RoadRunner Modern worker Microservices, job queues Medium No native HTTP/3 Yes Good
Swoole Async runtime High-concurrency I/O workloads High No native HTTP/3 Coroutine-based Good
LiteSpeed/OLS Web server WordPress, Apache migration Low Yes LSAPI (persistent) Excellent

Why Modern PHP Servers Use Go Under the Hood

You'll notice that both FrankenPHP and RoadRunner are written in Go. This isn't coincidence -- Go's goroutine-based concurrency model is well-suited for managing pools of PHP worker processes, handling HTTP connections, and coordinating I/O. It provides the high-concurrency connection handling that PHP's process model lacks, while letting PHP do what it does best: execute application logic.

Swoole takes the alternative approach of extending PHP itself with async primitives via a C extension, which avoids the Go dependency but requires more changes to how you write PHP code.

For most teams, the implementation language of the server doesn't matter -- what matters is the operational model and whether your application is compatible with persistent workers.

Deploying PHP Application Servers with DeployHQ

Whichever PHP server you choose, DeployHQ handles the deployment pipeline. Here's how DeployHQ integrates with each server type.

PHP-FPM and LiteSpeed Deployments

These are traditional deployments where DeployHQ excels. Your deployment pipeline typically looks like:

# Build commands (run in DeployHQ's build pipeline)
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache

# Post-deployment SSH command
sudo systemctl reload php8.5-fpm

DeployHQ's build pipelines run your Composer install and framework optimisation commands before uploading files. The zero-downtime deployment feature ensures your site stays live during the entire process -- old files serve requests until the new release is fully uploaded and symlinked.

FrankenPHP and RoadRunner Deployments

Worker-based servers need a graceful restart after deployment to pick up new code. Since workers keep your application in memory, simply uploading new files isn't enough -- you need to signal the server to reload.

# Post-deployment SSH command for FrankenPHP
sudo systemctl reload frankenphp

# Post-deployment SSH command for RoadRunner
./rr reset

Configure these as post-deployment commands in DeployHQ. The server gracefully finishes in-flight requests, then loads the new code.

Swoole Deployments

Swoole-based applications (including Laravel Octane with Swoole) follow a similar pattern to RoadRunner:

# Post-deployment SSH command
php artisan octane:reload

Key DeployHQ Features for PHP Deployments

  • Build pipelines: Run composer install, asset compilation, and framework optimisation commands before deployment
  • Zero-downtime deployments: Atomic symlink switching ensures your site never goes offline during deployment
  • Post-deployment hooks: Restart PHP-FPM, reload FrankenPHP workers, or reset RoadRunner processes after code is deployed
  • Rollback support: If a deployment causes issues, roll back to any previous release instantly
  • Multi-environment support: Deploy to staging with one PHP server configuration and production with another

If you're deploying PHP applications and want to learn more about deployment strategies, see our guide on deploying PHP applications with DeployHQ.

How to Choose the Right PHP Server

The decision comes down to three factors: your application's performance profile, your team's operational expertise, and your willingness to modify application code.

Stay with PHP-FPM if:

  • Your application performs well and you have no specific bottleneck at the PHP layer
  • You're running WordPress, Drupal, or other CMS platforms
  • You want the broadest compatibility and easiest hiring

Move to FrankenPHP if:

  • Framework bootstrap time is your biggest performance bottleneck
  • You want a simpler deployment (single binary, automatic TLS)
  • You're starting a new Laravel or Symfony project

Move to RoadRunner if:

  • You need built-in job queues, gRPC, or microservice infrastructure
  • You want a mature worker server with years of production track record
  • You're using Spiral Framework or building service-oriented architectures

Move to Swoole if:

  • Your application makes many concurrent I/O calls per request
  • You need true async capabilities (WebSockets, real-time features)
  • Your team is comfortable with async programming patterns

Move to LiteSpeed if:

  • You're running WordPress and want the fastest possible page loads
  • You're migrating from Apache and need .htaccess compatibility
  • You need HTTP/3 with minimal configuration effort

Frequently Asked Questions

Is FrankenPHP production-ready?

Yes. FrankenPHP has been used in production by multiple organisations and has official integration with both Symfony and Laravel. That said, it's a younger project than PHP-FPM or RoadRunner, so thorough testing in your specific environment is recommended before migration.

Can I switch from PHP-FPM to FrankenPHP without changing my code?

For most applications, yes. FrankenPHP's classic mode works as a drop-in replacement. Worker mode requires ensuring your application handles persistent state correctly (no global variable leaks, proper service container resets). Laravel and Symfony both provide guidance for worker-mode compatibility.

What happened to OpenSwoole?

OpenSwoole was a fork of Swoole that operated independently for a period. The project has since reverted to the original Swoole name. If you see references to OpenSwoole in older articles, they're referring to the same technology now maintained as Swoole.

Do I need to learn Go to use FrankenPHP or RoadRunner?

No. Both servers are distributed as pre-built binaries or Docker images. You configure them via configuration files (Caddyfile for FrankenPHP, .rr.yaml for RoadRunner) and interact with them through CLI commands. Go knowledge is only needed if you want to build custom server plugins.

Which PHP server is fastest?

There's no single answer. For I/O-bound workloads with many database queries, Swoole's coroutine model typically achieves the highest throughput. For CPU-bound or framework-heavy workloads, FrankenPHP and RoadRunner's worker modes provide similar performance gains by eliminating bootstrap overhead. PHP-FPM with proper tuning (opcache, preloading) remains competitive for many real-world applications. Always benchmark with your actual application rather than relying on synthetic tests.

Can I use DeployHQ with any of these servers?

Yes. DeployHQ deploys your code via SSH regardless of which application server you use. The difference is in your post-deployment commands: systemctl reload php-fpm for PHP-FPM, systemctl reload frankenphp for FrankenPHP, ./rr reset for RoadRunner, or php artisan octane:reload for Swoole via Laravel Octane. Get started with DeployHQ free.

How does LiteSpeed compare to Nginx with PHP-FPM?

LiteSpeed's LSAPI handler is generally faster than FastCGI for PHP execution, and its built-in caching (LSCache) provides significant performance improvements -- especially for WordPress. Nginx with PHP-FPM offers more flexibility for complex configurations and reverse proxy setups. If you're running WordPress or migrating from Apache, LiteSpeed is worth evaluating. For custom PHP applications, the difference is less pronounced.


Looking for a reliable way to deploy your PHP applications? Try DeployHQ free -- set up build pipelines, zero-downtime deployments, and post-deployment hooks for any PHP server in minutes.

Written by

Facundo F

Facundo | CTO | DeployHQ | Continuous Delivery & Software Engineering Leadership - As CTO at DeployHQ, Facundo leads the software engineering team, driving innovation in continuous delivery. Outside of work, he enjoys cycling and nature, accompanied by Bono 🐶.