2026年11月12日
2026年11月12日
WordPress OPcache on PHP-FPM: Settings, Status Checks and Clearing
This article is a localized edition of the Japanese original. Read the Japanese original
OPcache stores the compiled form of PHP scripts (opcodes) in shared memory so that later requests can skip compilation. WordPress loads hundreds of PHP files for every page view, so whether OPcache is enabled and whether it has enough memory makes a real difference to response times.
This article shows how to check and configure OPcache for the PHP-FPM that runs WordPress. Paths follow Ubuntu 24.04 (PHP 8.3) as of October 2026. For other versions, replace 8.3 accordingly.
The command line and PHP-FPM have separate settings
The first thing to know is that the php command (CLI) and PHP-FPM (the web side) read separate configuration files and keep separate caches.
| Configuration directory (Ubuntu) | OPcache default | |
|---|---|---|
CLI (php, WP-CLI) |
/etc/php/8.3/cli/ |
opcache.enable_cli=0 (off) |
| PHP-FPM (web) | /etc/php/8.3/fpm/ |
opcache.enable=1 (on) |
So if you check the status from the CLI, for example with php -r 'var_dump(opcache_get_status());', you will normally just get false (disabled), which tells you nothing about the web side. For the same reason, running wp eval 'opcache_reset();' only clears the CLI cache; the PHP-FPM cache stays as it is.
Check whether OPcache is enabled in PHP-FPM
You can see the settings PHP-FPM has loaded with this command:
php-fpm8.3 -i | grep -E '^opcache\.(enable|memory_consumption|interned_strings_buffer|max_accelerated_files|validate_timestamps|revalidate_freq|jit) '
In the WordPress admin, "Tools → Site Health → Info → Server" also shows the PHP version and SAPI, but not OPcache usage (free memory or hit rate). To see usage, you have to call opcache_get_status() on the web side.
A small plugin that shows usage in the admin
Save the following file as wp-content/mu-plugins/opcache-status.php and usage appears under "Tools → OPcache Status". Only administrators (users with the manage_options capability) can see it. Feel free to delete it once you are done checking.
<?php
/**
* Plugin Name: OPcache Status (admin screen)
*/
add_action( 'admin_menu', function () {
add_management_page( 'OPcache Status', 'OPcache Status', 'manage_options', 'opcache-status', function () {
if ( ! function_exists( 'opcache_get_status' ) ) {
echo '<div class="wrap"><p>The OPcache extension is not loaded.</p></div>';
return;
}
$s = opcache_get_status( false );
if ( ! $s ) {
echo '<div class="wrap"><p>OPcache is disabled, or calls are restricted by opcache.restrict_api.</p></div>';
return;
}
$mb = 1024 * 1024;
$mem = $s['memory_usage'];
$st = $s['opcache_statistics'];
$str = $s['interned_strings_usage'];
$rows = array(
'Used memory (MB)' => round( $mem['used_memory'] / $mb, 1 ),
'Free memory (MB)' => round( $mem['free_memory'] / $mb, 1 ),
'Wasted memory (%)' => round( $mem['current_wasted_percentage'], 2 ),
'String buffer used/total (MB)' => round( $str['used_memory'] / $mb, 1 ) . ' / ' . round( $str['buffer_size'] / $mb, 1 ),
'Cached scripts' => $st['num_cached_scripts'],
'Keys / limit' => $st['num_cached_keys'] . ' / ' . $st['max_cached_keys'],
'Hit rate (%)' => round( $st['opcache_hit_rate'], 2 ),
'Restarts (out of memory)' => $st['oom_restarts'],
'Restarts (out of keys)' => $st['hash_restarts'],
'Full (cache_full)' => $s['cache_full'] ? 'yes' : 'no',
);
echo '<div class="wrap"><h1>OPcache Status</h1><table class="widefat striped"><tbody>';
foreach ( $rows as $label => $value ) {
printf( '<tr><th>%s</th><td>%s</td></tr>', esc_html( $label ), esc_html( (string) $value ) );
}
echo '</tbody></table></div>';
} );
} );
These are the items to look at:
| Item | Condition | Action |
|---|---|---|
| Free memory | Close to 0, and cache_full is "yes" |
Increase opcache.memory_consumption |
| String buffer | Usage close to the total | Increase opcache.interned_strings_buffer |
| Keys / limit | Close to the limit, and "Restarts (out of keys)" keeps rising | Increase opcache.max_accelerated_files |
| Restarts (out of memory) | Not 0 | Increase opcache.memory_consumption |
The hit rate is low right after PHP-FPM starts or the cache is cleared. Check it after the site has been running for a while.
Choose the values
Here are the defaults of the main settings (from the PHP manual) and reasonable values for WordPress.
| Setting | Default | Guideline |
|---|---|---|
opcache.memory_consumption |
128 (MB) | 128 to 256. If you have many plugins or run several sites on the same PHP-FPM, increase it based on the usage figures above |
opcache.interned_strings_buffer |
8 (MB) | Around 16. Adjust based on usage |
opcache.max_accelerated_files |
10000 | More than the number of PHP files on the site. The actual limit is the smallest prime at or above the value you set (223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407 …) |
opcache.validate_timestamps |
1 | See "Checking for file changes" below |
opcache.revalidate_freq |
2 (seconds) | With validate_timestamps=1, how often (in seconds) files are checked for changes |
opcache.save_comments |
1 | Leave it at 1. Setting it to 0 breaks libraries that read doc comments |
Count the PHP files like this. If several sites share the same PHP-FPM pool, use the total for all of them.
find /var/www -type f -name '*.php' | wc -l
Put the settings in a new file that only FPM reads. /etc/php/8.3/mods-available/opcache.ini is read by both the CLI and FPM, so don't use it here.
; /etc/php/8.3/fpm/conf.d/99-opcache-wordpress.ini
opcache.enable=1
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
Apply the change and confirm the new values:
sudo php-fpm8.3 -t
sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep -E '^opcache\.(memory_consumption|max_accelerated_files|revalidate_freq) '
Watch out for settings from older articles
| Setting | Current status |
|---|---|
opcache.fast_shutdown |
Removed in PHP 7.2.0. It has no effect (the equivalent behavior happens automatically) |
opcache.cache_id |
Windows only. It lets processes with the same user, the same SAPI and the same ID share a cache; it has nothing to do with how files with errors are handled |
opcache.enable_cli=1 |
CLI runs end after each command, so it usually doesn't speed anything up. Leave the default of 0 |
Checking for file changes (validate_timestamps)
With opcache.validate_timestamps=1 (the default), OPcache checks file modification times every revalidate_freq seconds and recompiles files that changed. With revalidate_freq=60, old code can run for up to 60 seconds after you change a file, but the checks happen less often.
With opcache.validate_timestamps=0, OPcache stops checking altogether, so after you change a file the old code keeps running until the cache is cleared. In WordPress, keep the following in mind:
- When you update plugins, themes or core from the admin, WordPress (5.5 and later) invalidates the cache of the files it copied with
wp_opcache_invalidate(). This runs in the web process, so it affects the PHP-FPM cache. - When you update with WP-CLI (
wp plugin updateand so on), the invalidation runs in the CLI process and never reaches the PHP-FPM cache. - When you replace files with
git pull,rsync, FTP and the like, the cache is not cleared automatically either.
Use validate_timestamps=0 only if your deployment process can reload PHP-FPM; otherwise it is safer to leave it at 1 and tune revalidate_freq.
Clear the cache
The simplest way to clear the PHP-FPM cache is to reload PHP-FPM.
sudo systemctl reload php8.3-fpm
Run this command at the end of a deployment or after updating with WP-CLI. As explained above, wp eval 'opcache_reset();' and php -r 'opcache_reset();' only clear the CLI cache.
On shared hosting without shell access, you would have to call opcache_reset() over the web. However, many shared hosts run with opcache.validate_timestamps=1, so replaced files are usually picked up within revalidate_freq seconds. Check the actual values in your host's control panel or with phpinfo().
Should you use JIT with WordPress?
Since PHP 8.0, OPcache includes a JIT (which compiles code to native machine code at run time). The defaults differ by PHP version.
| PHP | opcache.jit default |
opcache.jit_buffer_size default |
Result |
|---|---|---|---|
| 8.0–8.3 | tracing |
0 |
The buffer is 0, so JIT doesn't run |
| 8.4 and later | disable |
64M |
JIT doesn't run |
Either way, JIT is not used with the defaults. JIT suits compute-heavy work, and its effect tends to be small for WordPress, which spends most of its time on database and file I/O. If you want to try it, enable it on a staging environment as shown below, measure response times, and compare before using it in production.
opcache.jit=tracing
opcache.jit_buffer_size=64M
Enabling JIT uses shared memory for jit_buffer_size on top of opcache.memory_consumption.
Related articles
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)