FrankenPHP, OPcache JIT &amp; Preloading for Laravel | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    FrankenPHP, OPcache JIT, and Preloading: Squeezing Real Throughput from Laravel        On this page       1. [  Why the PHP Runtime Layer Still Matters ](#why-the-php-runtime-layer-still-matters)
2. [  OPcache and JIT: What They Actually Do ](#opcache-and-jit-what-they-actually-do)
3. [  Preloading: Boot Laravel Once, Serve Forever ](#preloading-boot-laravel-once-serve-forever)
4. [  FrankenPHP: Eliminating the FPM Boundary ](#frankenphp-eliminating-the-fpm-boundary)
5. [  Worker Mode — The Real Win ](#worker-mode-the-real-win)
6. [  State Leakage in Worker Mode ](#state-leakage-in-worker-mode)
7. [  Combining All Three ](#combining-all-three)
8. [  Key Takeaways ](#key-takeaways)

  ![FrankenPHP, OPcache JIT, and Preloading: Squeezing Real Throughput from Laravel](https://cdn.msaied.com/423/7767da7948280307224437f4ab254e7d.png)

  #laravel   #frankenphp   #performance   #opcache   #php  

 FrankenPHP, OPcache JIT, and Preloading: Squeezing Real Throughput from Laravel 
=================================================================================

     14 Jul 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Why the PHP Runtime Layer Still Matters  ](#why-the-php-runtime-layer-still-matters)
2. [  02   OPcache and JIT: What They Actually Do  ](#opcache-and-jit-what-they-actually-do)
3. [  03   Preloading: Boot Laravel Once, Serve Forever  ](#preloading-boot-laravel-once-serve-forever)
4. [  04   FrankenPHP: Eliminating the FPM Boundary  ](#frankenphp-eliminating-the-fpm-boundary)
5. [  05   Worker Mode — The Real Win  ](#worker-mode-the-real-win)
6. [  06   State Leakage in Worker Mode  ](#state-leakage-in-worker-mode)
7. [  07   Combining All Three  ](#combining-all-three)
8. [  08   Key Takeaways  ](#key-takeaways)

 Why the PHP Runtime Layer Still Matters
---------------------------------------

Most Laravel performance conversations stop at query optimization or Redis caching. The runtime layer — how PHP itself boots, compiles, and executes your code — is often left at defaults. FrankenPHP, OPcache JIT, and preloading each attack a different slice of that cost.

---

OPcache and JIT: What They Actually Do
--------------------------------------

OPcache caches the compiled opcode of every PHP file so subsequent requests skip parsing and compilation. JIT (Just-In-Time compilation) goes one step further: it compiles hot opcode paths to native machine code at runtime.

For Laravel, the practical gain from JIT is **modest on I/O-bound routes** (most web requests) but **measurable on CPU-bound work** — think report generation, data transformation pipelines, or heavy collection operations.

```ini
; php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0   ; production only

; JIT — tracing mode is the most effective for web workloads
opcache.jit=tracing
opcache.jit_buffer_size=128M

```

`opcache.validate_timestamps=0` is critical in production. With it enabled, OPcache stat-checks every file on every request, which defeats much of the benefit.

---

Preloading: Boot Laravel Once, Serve Forever
--------------------------------------------

Preloading (PHP 7.4+) lets you load and compile classes into shared memory before any request is served. Every worker process inherits that memory map, skipping file I/O and compilation for preloaded classes entirely.

Laravel ships with a preload script you can publish:

```bash
php artisan vendor:publish --tag=laravel-preload

```

This generates `storage/framework/preload.php`. Point OPcache at it:

```ini
opcache.preload=/var/www/html/storage/framework/preload.php
opcache.preload_user=www-data

```

The generated script uses `Illuminate\Foundation\Application::preload()` to walk the framework's class map. You can extend it with your own hot paths:

```php
// storage/framework/preload.php
require __DIR__ . '/../../../vendor/autoload.php';

$app = require __DIR__ . '/../../../bootstrap/app.php';

// Preload your most-hit domain classes
require_once __DIR__ . '/../../../app/Domain/Pricing/PriceCalculator.php';
require_once __DIR__ . '/../../../app/Http/Resources/ProductResource.php';

```

Keep the preload list focused. Preloading everything inflates shared memory and can actually hurt cold-start time on low-traffic servers.

---

FrankenPHP: Eliminating the FPM Boundary
----------------------------------------

FrankenPHP is a PHP app server written in Go that embeds the PHP interpreter directly. It replaces Nginx + PHP-FPM with a single binary. The key architectural difference: no Unix socket or TCP hop between the web server and PHP.

### Worker Mode — The Real Win

FrankenPHP's worker mode is analogous to Laravel Octane's approach: PHP boots once, then handles requests in a loop without re-bootstrapping the framework.

```dockerfile
# Dockerfile (production)
FROM dunglas/frankenphp:latest-php8.3

COPY . /app
WORKDIR /app

RUN install-php-extensions pdo_pgsql redis intl

CMD ["frankenphp", "run", "--config", "/app/Caddyfile"]

```

```php
# Caddyfile
{
    frankenphp
    order php_server before file_server
}

localhost {
    root * /app/public
    php_server {
        worker /app/public/index.php
        num 4
    }
}

```

The `worker` directive tells FrankenPHP to keep `index.php` alive. Laravel's bootstrap runs once per worker, not once per request.

### State Leakage in Worker Mode

The same caution that applies to Octane applies here. Singletons bound in the container survive across requests. Reset them explicitly:

```php
// public/index.php (worker entry point)
require __DIR__ . '/../vendor/autoload.php';

$app = require_once __DIR__ . '/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

while ($request = \FrankenPHP\handle_request()) {
    $response = $kernel->handle(
        $illuminateRequest = Illuminate\Http\Request::createFromGlobals()
    );
    $response->send();
    $kernel->terminate($illuminateRequest, $response);
}

```

If you use Laravel Octane's `RequestHandled` flush hooks, those translate cleanly here.

---

Combining All Three
-------------------

The layers are additive:

1. **OPcache** — eliminates parse/compile overhead on every request.
2. **Preloading** — moves framework class loading to server boot, not request time.
3. **JIT** — compiles hot opcode to native code for CPU-bound paths.
4. **FrankenPHP worker mode** — eliminates framework bootstrap cost per request entirely.

---

Key Takeaways
-------------

- Set `opcache.validate_timestamps=0` in production; use deployment hooks to clear the cache on deploy.
- JIT's biggest gains are on CPU-bound code; don't expect dramatic wins on typical CRUD routes.
- Keep your preload list to genuinely hot classes — framework core plus your own domain hotspots.
- FrankenPHP worker mode and Octane share the same state-leakage risks; audit your singletons before enabling either.
- All three optimizations are orthogonal and compose cleanly — enable them incrementally and profile between each change.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffrankenphp-opcache-jit-and-preloading-squeezing-real-throughput-from-laravel-2&text=FrankenPHP%2C+OPcache+JIT%2C+and+Preloading%3A+Squeezing+Real+Throughput+from+Laravel) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffrankenphp-opcache-jit-and-preloading-squeezing-real-throughput-from-laravel-2) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Do I need Laravel Octane if I'm already using FrankenPHP worker mode?        Not necessarily. FrankenPHP worker mode achieves the same core benefit as Octane — keeping the framework bootstrapped between requests. Octane adds conveniences like table caches and explicit flush callbacks, but the raw performance mechanism is equivalent. You can use Octane's FrankenPHP driver to get both. 

      Q02  Will OPcache JIT break any Laravel application code?        In practice, JIT is transparent to application code — it operates at the opcode level. The rare issues reported historically involved specific ext-* extensions or code that relied on precise memory layout, neither of which is a concern for standard Laravel applications. 

      Q03  How do I clear the preload cache after a deployment?        Preloaded classes live in shared memory tied to the PHP-FPM or FrankenPHP worker process. A graceful worker restart (e.g., `systemctl reload php8.3-fpm` or sending SIGUSR2 to FrankenPHP) clears and rebuilds the preload cache from the updated files. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![New in Laravel 13: First-Party Image Manipulation](https://cdn.msaied.com/427/504aed7f9f1c4a1cd411c7c4a4b6bc7c.png) Laravel 13 Image Manipulation PHP 

### New in Laravel 13: First-Party Image Manipulation

Laravel 13 introduces a first-party image manipulation feature, removing the need for third-party packages for...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/new-in-laravel-13-first-party-image-manipulation) [ ![Filament v4 Testing with Pest: Resources, Actions, and Form Assertions](https://cdn.msaied.com/426/a81430a378b2849b6fbecb8235b9119f.png) filament pest testing 

### Filament v4 Testing with Pest: Resources, Actions, and Form Assertions

A practical guide to testing Filament v4 panels using Pest — covering resource page assertions, table action d...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/filament-v4-testing-with-pest-resources-actions-and-form-assertions) [ ![Laravel Legacy Bridge: Carry Authenticated Sessions from a Legacy PHP App into Laravel](https://cdn.msaied.com/429/5abced4ee695d6c03e3ae41bbf2fe4bb.png) Laravel PHP Session Management 

### Laravel Legacy Bridge: Carry Authenticated Sessions from a Legacy PHP App into Laravel

Laravel Legacy Bridge is a package that reads a legacy session cookie, decodes the payload from the legacy dat...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-legacy-bridge-carry-authenticated-sessions-from-a-legacy-php-app-into-laravel) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
