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](https://frankenphp.dev/) 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](https://roadrunner.dev/) 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](https://www.swoole.com/) 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](https://www.litespeedtech.com/) is a commercial web server with a drop-in Apache replacement and a built-in PHP handler (LSAPI). [OpenLiteSpeed](https://openlitespeed.org/) 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](https://www.deployhq.com/signup) handles the deployment pipeline. Here's how [DeployHQ](https://www.deployhq.com) integrates with each server type.

### PHP-FPM and LiteSpeed Deployments

These are traditional deployments where [DeployHQ](https://www.deployhq.com) 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](https://deployhq.com/blog/build-pipelines-in-deployhq-streamline-your-deployment-workflow) run your Composer install and framework optimisation commands before uploading files. The [zero-downtime deployment](https://deployhq.com/blog/zero-downtime-deployments-keeping-your-application-running-smoothly) 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](https://www.deployhq.com). 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](https://deployhq.com/blog/build-pipelines-in-deployhq-streamline-your-deployment-workflow)**: Run `composer install`, asset compilation, and framework optimisation commands before deployment
- **[Zero-downtime deployments](https://deployhq.com/features/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](https://www.deployhq.com) 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](https://deployhq.com/blog/5-powerful-ways-to-deploy-php-applications-with-deployhq). For framework-specific walkthroughs across Composer, Laravel, and WordPress, see [how to deploy a PHP site with DeployHQ](https://www.deployhq.com/blog/deploying-your-php-site-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](https://www.deployhq.com) 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](https://deployhq.com/signup)[DeployHQ](https://www.deployhq.com) 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](https://www.deployhq.com) free_](https://deployhq.com/signup) _-- set up build pipelines, zero-downtime deployments, and post-deployment hooks for any PHP server in minutes._

