How to Deploy Laravel 11 with Nginx, PHP 8.3 & FrankenPHP / Octane on VPS

Laravel 11 is the gold standard for enterprise web application development in PHP. However, traditional PHP-FPM deployment architectures suffer from an inherent performance ceiling: on every single incoming HTTP request, the PHP runtime must boot the entire Laravel framework, register service providers, parse configuration arrays, and compile route trees before executing a single line of business logic.

By deploying Laravel 11 with Laravel Octane powered by FrankenPHP—a modern, Go-based application server written by Kévin Dunglas—your application boots once and remains resident in system memory. Request handling transitions from hundreds of milliseconds to sub-5ms latencies, capable of sustaining 5,000+ requests per second on a standard Linux VPS. In this tutorial, you will learn how to configure FrankenPHP, optimize Octane worker pools, configure Redis queue daemons, and manage zero-downtime deployments.

1. Understanding the FrankenPHP Octane Architecture

FrankenPHP combines the Caddy web server core with an embedded C-based PHP SAPI:

  • Zero Boot Overhead: FrankenPHP boots Laravel once upon daemon startup. Subsequent HTTP requests execute inside existing memory threads, bypassing repetitive framework initialization.
  • Early Hints & HTTP/3: FrankenPHP provides out-of-the-box support for 103 Early Hints and native HTTP/3 (QUIC) over UDP, pre-loading frontend assets before HTML bodies stream.
  • Automated Worker Recycling: Automatically recycles worker threads after a specified number of requests to prevent memory leaks in legacy packages.

2. Installing Prerequisites on Ubuntu 24.04 VPS

Install PHP 8.3 CLI, required extensions, Redis server, and Composer:

# Install Ondřej Surý PHP repository
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update && sudo apt install -y php8.3-cli php8.3-common php8.3-mysql php8.3-redis     php8.3-xml php8.3-curl php8.3-mbstring php8.3-zip php8.3-bcmath php8.3-intl     redis-server git unzip supervisor

# Install Composer globally
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

3. Installing and Configuring Laravel Octane with FrankenPHP

Inside your Laravel 11 application directory, install Laravel Octane via Composer:

cd /var/www/my-laravel-app
composer require laravel/octane

# Run the Octane installation wizard and select 'frankenphp'
php artisan octane:install --server=frankenphp

Octane automatically downloads the optimized FrankenPHP binary directly into your project root. Configure your environment variables in .env:

OCTANE_SERVER=frankenphp
OCTANE_HTTPS=true
OCTANE_WORKERS=auto
OCTANE_MAX_REQUESTS=1000

4. Production systemd Service Configuration

Never run Octane manually inside a terminal screen. Create a dedicated systemd service unit at /etc/systemd/system/laravel-octane.service to manage background restarts and port binding:

[Unit]
Description=Laravel Octane FrankenPHP High-Performance Server
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/my-laravel-app
ExecStart=/usr/bin/php8.3 /var/www/my-laravel-app/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000 --workers=4 --max-requests=1000
Restart=always
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

Reload systemd and start the Octane service:

sudo systemctl daemon-reload
sudo systemctl enable --now laravel-octane
sudo systemctl status laravel-octane

5. Nginx Front-End Reverse Proxy Configuration

Place an Nginx reverse proxy in front of FrankenPHP to manage SSL termination, public static asset caching, and WebSocket connections:

server {
    listen 443 ssl http2;
    server_name api.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    root /var/www/my-laravel-app/public;
    index index.php;

    # Serve static assets directly from disk
    location ~* \.(jpg|jpeg|gif|png|css|js|ico|svg|woff|woff2)$ {
        expires 30d;
        access_log off;
    }

    # Proxy application requests to FrankenPHP Octane
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

When deploying updates in production, execute php artisan octane:reload to trigger zero-downtime hot reloading of modified PHP classes without dropping active HTTP connections.

5. Configuring Laravel Octane Worker Watchers & Memory Leak Mitigation

Because Laravel Octane keeps the entire framework bootstrapped in memory (unlike standard PHP-FPM which executes a fresh lifecycle per request), static variables and singleton service container bindings persist between HTTP requests. This architectural difference requires specific operational hygiene:

  • State Resetting Between Requests: Register service providers that maintain request-specific state in the warm array inside config/octane.php. Octane automatically clears standard bindings (such as authenticated users, current session, and resolved request objects) before handling the next inbound connection.
  • Mitigating Memory Leaks with Max Requests: Even well-audited third-party Composer packages can introduce minor memory leaks. Safeguard your production server by enforcing an automatic worker recycling threshold:
    php artisan octane:start --server=frankenphp --workers=4 --max-requests=1000

    Once an individual FrankenPHP worker serves 1,000 requests, Octane seamlessly reboots that worker in the background while remaining workers continue serving traffic without latency spikes.

  • File Change Watcher in Staging: Use --watch during testing with Chokidar to automatically reload workers when PHP files are modified, matching standard FPM developer experience during staging rollouts.

6. Automated Horizon Queue Monitoring & Redis Cluster Tuning

High-concurrency Laravel architectures offload transactional workloads to background workers managed by Laravel Horizon:

# /etc/systemd/system/laravel-horizon.service
[Unit]
Description=Laravel Horizon Process Supervisor
After=network.target redis.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/laravel
ExecStart=/usr/bin/php /var/www/laravel/artisan horizon
ExecReload=/usr/bin/php /var/www/laravel/artisan horizon:terminate
Restart=always
RestartSec=3s

[Install]
WantedBy=multi-user.target

Horizon provides real-time dashboard analytics on queue wait times, job throughput, and failed job exceptions, ensuring rock-solid asynchronous execution.

7. Production OPCache & JIT Compiler Tuning for Laravel 11

To squeeze maximum raw execution speed out of PHP 8.3 and FrankenPHP, fine-tuning the Zend OPcache and JIT (Just-In-Time) compiler parameters provides significant throughput improvements:

  • OPcache Memory Allocation: Inside your PHP configuration (/etc/php/8.3/cli/conf.d/10-opcache.ini), increase shared memory buffers to prevent cache evictions during heavy deployment cycles:
    opcache.enable=1
    opcache.enable_cli=1
    opcache.memory_consumption=256
    opcache.interned_strings_buffer=32
    opcache.max_accelerated_files=20000
    opcache.validate_timestamps=0
    opcache.save_comments=1
  • Configuring Tracing JIT: Set opcache.jit=tracing and opcache.jit_buffer_size=128M. Tracing JIT identifies frequently executed bytecode loops and compiles them directly into native machine code, speeding up CPU-bound operations such as JSON serialization, cryptographic hashing, and complex data formatting by up to 2.5x.
  • Validating Active JIT Status: Verify that JIT is engaged by running php -r 'var_dump(opcache_get_status()["jit"]);' in the terminal.

Scale Laravel Applications on CpanelFree Cloud VPS

Give Octane and Redis the dedicated compute power they deserve. Experience ultra-low latency, NVMe speeds, and high-concurrency stability with CpanelFree.

Discover CpanelFree High-Speed VPS →

Leave a Comment