Laravel Octane fundamentally changes how your PHP application handles requests. Instead of booting the framework from scratch on every single request — loading configuration, registering service providers, resolving bindings — Octane boots the application once and keeps it in memory, serving subsequent requests from that warm state. The result is dramatically faster response times and significantly higher throughput.
Deploynix supports all three Octane drivers: FrankenPHP, RoadRunner, and Swoole. Each has its own strengths, trade-offs, and ideal use cases. In this guide, we will cover how to enable Octane on Deploynix, how to choose the right driver for your application, performance characteristics you can expect, and the gotchas you need to watch out for when moving from traditional PHP-FPM to an Octane-powered setup.
How Octane Changes the Game
To understand why Octane matters, you need to understand how traditional PHP-FPM works.
With PHP-FPM, every incoming request triggers a full bootstrap of your Laravel application. The framework reads configuration files, registers service providers, boots services, resolves route middleware, and then finally handles your request. After the response is sent, everything is destroyed. The next request starts from scratch.
This model is simple and safe. There is no shared state between requests, so memory leaks are impossible and every request gets a clean environment. But it is also wasteful. If your application takes 30-50 milliseconds just to boot, that overhead exists on every single request, regardless of how simple the actual work is.
Octane eliminates this overhead by booting the application once and keeping it resident in memory. The framework is fully initialized, service providers are registered, and the application is ready to handle requests without any bootstrap cost. A request that previously took 80 milliseconds might now take 15 milliseconds because 65 milliseconds of that was framework bootstrapping.
The difference is most dramatic for applications with many service providers, complex configurations, or heavy IoC container usage — which describes most real-world Laravel applications.
Choosing Your Driver
Deploynix supports all three Octane drivers. Here is how they compare.
FrankenPHP
FrankenPHP is the newest driver and the one that has generated the most excitement in the Laravel community. It is a modern PHP application server built on top of Caddy, written in Go. FrankenPHP supports early hints (HTTP 103), worker mode, and automatic HTTPS.
Strengths:
- Simplest setup process — single binary, no PHP extensions required
- Built-in HTTPS with automatic certificate management
- HTTP/3 and early hints support out of the box
- Active development with strong community momentum
- Worker mode keeps your application in memory similar to how Swoole does, but without needing a PHP extension
Best for: New projects and teams that want the simplest possible Octane setup with modern HTTP features.
Considerations: As the newest driver, it has the smallest ecosystem of community knowledge and troubleshooting resources, though this is growing rapidly.
RoadRunner
RoadRunner is a high-performance PHP application server written in Go. It has been around longer than FrankenPHP and has a proven track record in production environments.
Strengths:
- Mature and battle-tested in production
- No PHP extensions required — uses standard PHP workers
- Built-in support for queues, WebSockets, and gRPC
- Extensive plugin ecosystem
- Excellent documentation and community support
Best for: Production workloads where stability and proven performance are the priority. Particularly strong for applications that also need WebSocket or gRPC capabilities.
Considerations: Configuration is more involved than FrankenPHP. The .rr.yaml configuration file has many options that can be overwhelming at first.
Swoole
Swoole is a PHP extension that brings asynchronous, event-driven programming to PHP. It has been the Octane driver of choice for teams that need maximum performance and are comfortable with the trade-offs.
Strengths:
- Highest raw performance of the three drivers
- True asynchronous I/O — database queries, HTTP requests, and file operations can run concurrently
- Coroutine support for concurrent programming
- The most mature Octane driver with the longest track record
Best for: Applications where every millisecond counts, teams comfortable with PHP extensions, and use cases that benefit from asynchronous I/O (high-concurrency APIs, real-time applications).
Considerations: Requires the Swoole PHP extension, which adds complexity to your server configuration. Some PHP libraries are not Swoole-compatible. The async programming model can introduce subtle bugs if you are not careful.
Enabling Octane on Deploynix
Step 1: Install Octane in Your Application
First, add Octane to your Laravel application:
composer require laravel/octane
Then publish the Octane configuration:
php artisan octane:install
During installation, you will be asked to choose a driver. Select the one you want to use. This creates the config/octane.php configuration file.
Step 2: Configure Your Deploynix Site
In your Deploynix dashboard, navigate to your site's settings. Look for the Octane configuration section.
Enable Octane and select your driver (FrankenPHP, RoadRunner, or Swoole).
When you enable Octane, Deploynix reconfigures Nginx to proxy requests to the Octane server instead of PHP-FPM. The Octane process is managed by Supervisor, ensuring it restarts automatically if it crashes or if the server reboots.
Deploynix handles the Octane setup automatically by running composer require laravel/octane and php artisan octane:install with your chosen driver. Laravel's Octane installer takes care of downloading the appropriate driver binary or configuring the required extension.
For FrankenPHP, no additional PHP extensions are needed — the driver is installed via Composer.
For RoadRunner, the binary is downloaded and a .rr.yaml configuration is generated during installation.
For Swoole, the Swoole PHP extension must be available on the server. If it is not already installed, you can install it via SSH before enabling Octane.
Step 3: Configure Workers
The number of Octane workers determines how many concurrent requests your application can handle. A good starting point is to match the number of CPU cores on your server.
For a 2 vCPU server, start with 2 workers. For a 4 vCPU server, start with 4 workers. You can adjust this based on monitoring data once your application is running.
Set the OCTANE_WORKERS environment variable or configure it in config/octane.php:
'workers' => env('OCTANE_WORKERS', 4),
Step 4: Deploy
Trigger a deployment. Deploynix will install your Octane driver, configure Nginx, start the Octane server process, and begin routing traffic through it.
Performance Expectations
The performance improvement you see from Octane depends heavily on your application's characteristics.
Request-heavy applications (APIs serving many small, fast requests) see the most dramatic improvement because the framework bootstrap overhead is a larger proportion of total request time. A simple API endpoint that took 40 milliseconds with FPM might take 5-10 milliseconds with Octane.
Database-heavy applications see a smaller relative improvement because the database query time dominates. If your endpoint takes 200 milliseconds and 180 milliseconds of that is database queries, Octane might bring the total to 160 milliseconds — a noticeable improvement, but not the 4-8x speedup you see with lighter workloads.
Throughput (requests per second) typically improves by 2-4x for most applications. Since each request is processed faster and workers are reused without bootstrap overhead, the same server can handle significantly more traffic.
A Rough Benchmark Guide
These numbers are illustrative, not guaranteed. Your results will vary based on your application.
| Metric | PHP-FPM | Octane (FrankenPHP) | Octane (RoadRunner) | Octane (Swoole) |
|---|---|---|---|---|
| Simple API response | 35-50ms | 5-12ms | 5-10ms | 3-8ms |
| Database query endpoint | 80-120ms | 50-80ms | 45-75ms | 40-70ms |
| Requests/sec (2 vCPU) | 200-400 | 800-1500 | 900-1600 | 1000-2000 |
| Memory per worker | 30-50MB | 40-60MB | 35-55MB | 45-65MB |
The Gotchas: What Breaks When You Switch
Octane's persistent application state is both its greatest strength and its most dangerous trap. Code patterns that work perfectly fine under PHP-FPM can cause subtle, hard-to-debug issues under Octane.
Static Properties and Singletons
Under PHP-FPM, static properties reset on every request. Under Octane, they persist across requests. If your code accumulates data in a static property, that data leaks between requests.
// DANGEROUS under Octane
class RequestLogger
{
public static array $logs = [];
public static function log(string $message): void
{
static::$logs[] = $message; // Grows forever!
}
}
Fix: Use Octane's flush callbacks to reset state between requests, or avoid static state altogether. Laravel's built-in services are already Octane-compatible, but third-party packages and custom code need auditing.
Container Resolved Singletons
If you bind a service as a singleton in the container and that service holds request-specific state (like the authenticated user), that state persists into the next request.
Fix: Use $app->scoped() instead of $app->singleton() for services that hold request-specific data. Scoped bindings are resolved once per request and flushed automatically.
Global Helpers Holding State
The request(), auth(), and session() helpers work correctly under Octane because Laravel resets them between requests. But if you cache the result of these helpers in a property during boot, that cached value persists.
// DANGEROUS under Octane
class SomeService
{
private User $user;
public function __construct()
{
$this->user = auth()->user(); // Cached forever!
}
}
Fix: Resolve request-specific data at the time of use, not at construction time.
File Handles and Database Connections
Long-lived workers can exhaust file handles or database connections over time. Octane manages this by recycling workers after a configurable number of requests.
Set the --max-requests option to periodically restart workers. Deploynix defaults to 500 max requests, which you can adjust in the Octane settings (range: 100–10,000):
php artisan octane:start --max-requests=500
This tells Octane to gracefully restart a worker after it has handled 500 requests, preventing memory leaks and stale connections from accumulating.
Third-Party Packages
Not all packages are Octane-compatible. Before enabling Octane, check the compatibility of your critical dependencies. The Laravel documentation maintains a list of known incompatibilities. Common issues include packages that use static state, persistent file locks, or singleton patterns that hold request-specific data.
Monitoring Your Octane Application
After switching to Octane, pay close attention to:
Memory usage per worker. Under FPM, memory is reclaimed after every request. Under Octane, workers persist, so memory leaks accumulate. Monitor worker memory usage through Deploynix's server monitoring dashboard and set up health alerts for high memory usage.
Response time consistency. Octane should deliver consistently fast responses. If you see occasional slow responses followed by fast ones, a worker might be encountering garbage collection pauses or memory pressure.
Error rates. Subtle Octane incompatibilities often manifest as intermittent errors rather than consistent failures. Monitor your error logs closely for the first few days after switching.
Falling Back to PHP-FPM
If you encounter issues with Octane that you cannot immediately resolve, switching back to PHP-FPM through the Deploynix dashboard is instant. Deploynix reconfigures Nginx to route requests back to PHP-FPM and stops the Octane process. Your application continues serving traffic without interruption.
This safety net means there is no risk in trying Octane. Enable it, monitor for a few days, and if everything looks good, keep it. If not, switch back with one click while you investigate.
Conclusion
Laravel Octane represents a significant leap in PHP application performance, and Deploynix makes enabling it straightforward regardless of which driver you choose. FrankenPHP offers simplicity and modern HTTP features, RoadRunner provides battle-tested stability, and Swoole delivers maximum raw performance.
The key to a successful Octane deployment is understanding that persistent application state changes the rules. Audit your code for static properties, singleton misuse, and request-specific data cached at construction time. Use Deploynix's monitoring tools to watch memory usage and response consistency.
Start with FrankenPHP if you want the easiest path, RoadRunner if you want proven stability, or Swoole if you want every last drop of performance. Deploynix supports all three, and switching between them is just a configuration change away.
Try Octane on your next deployment at deploynix.io.
Top comments (0)