Advanced OPcache Optimisation

Once you've enabled OPcache and set the basic configuration, there are several advanced techniques you can use to squeeze out even more performance and gain deeper insight into how your application is running. This guide covers preloading, monitoring, and optimising for command-line scripts—the tools an advanced PHP developer uses to master their production environment.

Gaining Maximum Performance with Preloading

Introduced in PHP 7.4, preloading is arguably the most powerful optimisation feature in OPcache's arsenal. It solves the "cache warm-up" problem by allowing you to load a specific set of your application's most important files into memory the moment the server starts.

The Concept

Normally, OPcache only caches a file after it has been requested at least once. This means the very first request for a page after a deployment will be slower, as PHP has to compile all the required files on the fly. Preloading eliminates this. The preloaded files are compiled once at startup and then exist in memory, ready to be used by all subsequent requests without any further checks or compilation.

How to Implement Preloading

Implementation involves two steps:

-Create a preload.php Script: This is a simple PHP file where you require all the files you want to preload. You should only preload your application's "hot" code—the core framework classes, services, and base controllers that are used on almost every request. Do not preload your entire application, as this will waste memory.

PHP


<?php
// preload.php
// Define the paths to your core directories
$paths = [
__DIR__ . '/vendor/my-framework/src',
__DIR__ . '/app/Core',
__DIR__ . '/app/Services',
];

foreach ($paths as $path) { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST );

foreach ($iterator as $file) {
    if ($file->isDir()) {
        continue;
    }

    if (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
        // This compiles the file and adds it to the cache
        opcache_compile_file($file->getRealPath());
    }
}

}

> - Configure 'php.ini`: Point to your preload script in your `php.ini` configuration.

###Ini, TOML
```ini
; Enable OPcache
opcache.enable=1

; Point to your preload script (use an absolute path)
opcache.preload=/var/www/my-app/preload.php

The Critical Trade-off: The power of preloading comes with a significant caveat. Once a file is preloaded, it is locked in memory. The only way to update it is to restart the PHP service (e.g., sudo systemctl restart php8.4-fpm). Your deployment script must account for this.

Monitoring and Fine-Tuning with opcache_get_status()

You shouldn't configure OPcache blindly. PHP provides the opcache_get_status() function to give you a detailed look inside the cache. This is essential for verifying your configuration and diagnosing performance issues.

The function returns a large array of data, but you'll want to focus on a few key metrics:

-memory_usage: Shows how much memory is consumed, how much is free, and the total wasted percentage (due to outdated scripts). If free_memory is consistently low, you need to increase opcache.memory_consumption.

-opcache_statistics: Contains the number of cached scripts, hits, and misses. The opcache_hit_rate is the most important metric here. In a well-configured production environment, this should be above 99%. A low hit rate indicates that PHP is frequently having to recompile scripts, and your cache settings may be incorrect.

  • scripts: A full list of every script in the cache, with details on its memory usage and hit count.

You can create a simple, secure admin page to display this information:

PHP

<?php
// A simple status viewer (protect this route!)
$status = opcache_get_status();
$stats = $status['opcache_statistics'];
echo "<h2>OPcache Status</h2>";
echo "<strong>Hit Rate:</strong> " . round($stats['opcache_hit_rate'], 2) . "%<br>";
echo "<strong>Memory Used:</strong> " . round($status['memory_usage']['used_memory'] / 1048576, 2) . " MB<br>";
echo "<strong>Cached Scripts:</strong> " . $stats['num_cached_scripts'] . "<br>";

Optimising for the Command Line (CLI)

By default, the in-memory OPcache is designed for a long-running web server process (like PHP-FPM). Each time you run php my_script.php from the command line, it's a new, short-lived process that gets its own clean slate—and therefore no benefit from the shared in-memory cache.

For applications with heavy CLI usage (e.g., cron jobs, command-line tools), you can enable a file-based cache.

Ini, TOML

``'ini ; in php.ini, specifically for the CLI SAPI opcache.file_cache=/var/tmp/opcache


This tells PHP to store the compiled opcodes in the specified directory. While reading from a disk is slower than reading from shared memory, it is still significantly faster than parsing and compiling your PHP source code on every single CLI execution. This provides a crucial performance boost for your command-line tools.

Cache Invalidation Strategies
When opcache.validate_timestamps is set to 0 for maximum performance, OPcache will never check for updated files. This means you need a deliberate strategy to clear the cache during a deployment. There are three main ways to do this.

Restarting the PHP Service (Recommended): This is the simplest and most reliable method. As part of your deployment script, you simply restart the PHP-FPM service (e.g., sudo systemctl restart php8.3-fpm). This completely destroys the old cache, and it will be rebuilt from scratch with the new files as they are requested. It’s clean, effective, and guarantees there's no stale code.

Using opcache_reset(): PHP provides this function to programmatically wipe the entire cache. You could create a secure script (e.g., accessible only from localhost or via a secret token) that you call via curl at the end of a deployment. While it avoids a full service restart, it can be more complex to secure properly and is generally less common than a service restart.

Using opcache_invalidate(): This function is more granular. It allows you to remove a specific script from the cache by passing its path. This is useful in very specific scenarios where you have a file that changes frequently and you don't want to invalidate the entire cache, but it's often too complex for a standard deployment workflow.

Understanding and Managing Wasted Memory
If you look at the opcache_get_status() output, you'll see a wasted_memory value. Memory becomes "wasted" when you update a file while opcache.validate_timestamps is turned on. OPcache will detect the new file, compile it, and cache it, but it will mark the memory used by the old version of that file as wasted. It won't be freed until the entire cache is cleared.

You can control this with the opcache.max_wasted_percentage directive in php.ini. This sets a threshold (e.g., 10 for 10%) at which OPcache will schedule a full cache reset if the wasted memory percentage is exceeded. In a production environment with timestamps turned off, this is less of an issue, but it's a critical setting for development or staging servers.

Security Considerations: opcache.restrict_api
The OPcache API functions (opcache_get_status(), opcache_reset(), etc.) are very powerful. You don't want any unauthorized script to be able to view detailed information about your server's code or, worse, wipe the cache and degrade your site's performance.

The opcache.restrict_api directive in php.ini helps prevent this. You can provide a path prefix, and only PHP scripts that begin with this path will be allowed to call the OPcache API functions. For example:

Ini, TOML

; Only scripts inside /var/www/my-app/admin/opcache/ can call opcache_* functions.
opcache.restrict_api=/var/www/my-app/admin/opcache/
This is a crucial security measure if you plan to build any kind of OPcache status dashboard.

##Summary: From User to Master 🚀

>Mastering OPcache goes far beyond simply enabling it in your `php.ini` file. As we've seen, it's a sophisticated system with powerful tools for almost every scenario you'll encounter in a production environment.

> By leveraging preloading, you can eliminate performance cold spots after a deployment. By actively monitoring the cache's status, you can make informed decisions to fine-tune your configuration. Understanding the correct invalidation strategies is key to a smooth and professional deployment workflow, while managing memory and security ensures your application remains stable and protected.

> These advanced techniques are what separate a developer who simply uses OPcache from one who truly masters it. Applying them correctly is a hallmark of a high-performance, production-ready application and a key skill for any senior PHP developer.

Shopping summary

Item

SubTotal: £

Empty Basket

this is a hidden panel

Completed in 29 milliseconds

Completed in 29 milliseconds

This is the top Panel

This is the bottom Panel