Skip to main content
Github

OPcache

OPcache improves PHP performance by storing pre-compiled code in shared memory, avoiding reading and recompiling for each request. This saves CPU usage and allows the server to handle significantly more simultaneous accesses.

This tutorial shows how to check, enable, configure, and validate OPcache on a production server.

Prerequisites

  • Access rootto or sudofrom the server
  • PHP 7.0 or higher (from PHP 5.5 onwards the extension comes with PHP; in PHP 8.x it is part of the core)
  • Find out which SAPI you are using: PHP-FPM (Nginx/Apache) or mod_php (Apache)

Step 1: Check if OPcache is already active.

php -v

If the output mentions with Zend OPcache, the extension is installed. To confirm if it is enabled:

php -i | grep -i "opcache.enable"

Step 2: Install the extension (if necessary)

Debian/Ubuntu

sudo apt update sudo apt install php8.5-opcache

RHEL/Rocky/AlmaLinux (Remi repository)

sudo dnf install php-opcache

Replace 8.5with the PHP version you are using.

Step 3: Locate the configuration file.

php --ini

Common places:

Distribution Path (FPM)
Debian/Ubuntu /etc/php/8.5/fpm/conf.d/10-opcache.ini
RHEL/Rocky /etc/php.d/10-opcache.ini

Tip: Instead of editing the default file (which can be overwritten in updates), create your own file with higher priority, for example 99-opcache-custom.iniin the same folder conf.d.

Step 4: Configure OPcache for production.

Create the file:

sudo nano /etc/php/8.5/fpm/conf.d/99-opcache-custom.ini

Recommended content:

[opcache] ; Enables OPcache opcache.enable=1 opcache.enable_cli=0 ; Memory reserved for bytecode (in MB) opcache.memory_consumption=256 ; Memory for interned strings (in MB) opcache.interned_strings_buffer=16 ; Maximum number of cached files. ; Must be greater than the number of .php files in the project. opcache.max_accelerated_files=20000 ; PRODUCTION: do not check if files have changed ; (higher performance; requires clearing the cache on every deployment) opcache.validate_timestamps=0 ; Only relevant if validate_timestamps=1 (interval in seconds) opcache.revalidate_freq=0 ; Prevents memory waste opcache.max_wasted_percentage=10 ; Stores the full file path in the cache opcache.use_cwd=1

Explanation of the main parameters

Directive Value Reason
opcache.enable 1 Enable cache
opcache.enable_cli 0 In the CLI, the cache does not persist between executions, so it's not helpful (except in long-running workers).
opcache.memory_consumption 256 The standard size (128 MB) is often insufficient for large projects.
opcache.max_accelerated_files 20000 Use a value greater than the total number of PHP files (include the comma vendor/) .
opcache.validate_timestamps 0 Eliminates calls stat()on each request, but requires a cache reset on deployment.

To count how many PHP files your project has:

find /var/www/meuapp -type f -name "*.php" | wc -l

Step 5 (optional): Preload (PHP 7.4+)

This opcache.preload=executes an arbitrary file that is run only once during server startup (PHP-FPM, mod_php, etc.) in persistent memory, which can be very useful in the framework.

Inphinit already provides a script for this use, located in system/boot/preload.php which can be edited manually to configure the most used classes in your application, and to use it, simply point to its location as in the example:

opcache.preload=/path/to/my-app/system/boot/preload.php opcache.preload_user=www-data

If you have a frequently used class, such as a class installed via composer, you can edit it by adding it to system/boot/preload.php, as in the example:

OPcache::preload(array( ..., Foo\Bar\Baz::class, ));

After modifying the file, it is necessary to restart PHP-FPM.

Step 6: Restart the service and validate.

Test the configuration before restarting:

sudo php-fpm8.5 -t

Restart:

sudo systemctl restart php8.5-fpm

If you are using Apache with mod_php, the command to restart is:

sudo systemctl restart apache2

Step 7: Clear the cache after each deployment.

With this validate_timestamps=0, the cache needs to be invalidated after each deployment. Options:

Option A: Reload PHP-FPM (the simplest and most reliable)

sudo systemctl reload php8.5-fpm

It reload's a nice feature: workers finish ongoing requests before being replaced, without taking down the service.

Option B: Call opcache_reset()via web request

Create a protected route (for example, accessible only via localhost ) and call it at the end of the deployment:

$app->action('GET', '/opcache/reset', function () { if (!in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'], true)) { http_response_code(403); } elseif (opcache_reset()) { return 'OPcache limpo.'; } return 'Falha ao limpar cache.'; });
curl -s http://127.0.0.1/opcache/reset

Problem solving

Symptom Probable cause Solution
Changes to the code are not showing up. validate_timestamps=0no reset Rode systemctl reload php8.5-fpm
opcache_get_status()returns false OPcache disabled in FPM Check out opcache.enable=1the FPM ini file.
Low success rate Cache full Increase memory_consumptionand max_accelerated_files
FPM does not increase after activating preload. Error in preload script Look journalctl -u php8.5-fpm

References