Tune OPcache and make PHP OPcache perform even better! Now that you’ve optimized PHP realpath_cache_size, it’s time to fine-tune OPcache. With just a few tweaks you can tune PHP OPcache to make it perform much better, and here is how…
PHP OPcache opcode cache
PHP OPcache is an opcode cache: OPcache improves PHP performance by storing precompiled script byte-code in shared memory, thereby removing the need for PHP to load and parse scripts on every request. This allows PHP to use the precompiled byte-code instead of compiling it on every request.
The OPcache extension is bundled with PHP 5.5.0 and later.
Protip: Wondering how to flush OPcache in WordPess?
OPcache default configuration
OPcache comes with a default configuration that can work perfectly in your environment. Use the opcache_get_status() function to get the current status information about the cache. This information is valuable for further optimizing your OPcache configuration and thus your PHP and website performance.
Some of the default OPcache configuration settings are:
; The OPcache shared memory storage size. ;opcache.memory_consumption=64 ; The amount of memory for interned strings in Mbytes. ;opcache.interned_strings_buffer=4 ; The maximum number of keys (scripts) in the OPcache hash table. ; Only numbers between 200 and 100000 are allowed. ;opcache.max_accelerated_files=2000 ; If enabled, a fast shutdown sequence is used for the accelerated code ;opcache.fast_shutdown=0
They’re commented out since they’re default.
Tune this default OPcache configuration
You can fine-tune PHP’s OPcache configuration by utilizing the
opcache_get_status() function. One piece of information it provides is current memory_usage:
[memory_usage] => Array ( [used_memory] => 41594440 [free_memory] => 21280800 [wasted_memory] => 4233624 [current_wasted_percentage] => 6.3085913658142 )
Values are in bytes, which makes the OPcache shared memory storage size 64 MB ((41594440 + 21280800 + 4233624) / 1048576).
Don’t forget, this 64 MB is for every website (in IIS terms: application pool or worker process). This means that 64 MB per website becomes 6400 MB – or 6,4 GB – for one hundred websites on your server. You need to have that available.
These numbers show me that I, in this particular situation, don’t need 64 MB shared memory storage. Trust me, the application runs for quite a while with this config so the numbers are valid, so to speak. Therefore, I can decrease the
opcache.memory_consumption setting to some 42+ MB, let’s say 48 MB to have something to spare:
If necessary you can also increase OPCache’s memory limit (opcache.memory_consumptions)
; default = opcache.memory_consumption=128 opcache.memory_consumption=150
opcache.interned_strings_buffer setting is an important one. String interning is a method of storing only one copy of each distinct string value, which must be immutable. For example, if I have the string “The quick brown fox jumps over the lazy dog” a hundred (100) times in my code, PHP will store 1 variable in memory. The 99 other times, a memory pointer is used to refer to this string.
I believe this happens a lot when you code, so in my opinion this setting may be increased:
; default = opcache.interned_strings_buffer=8 opcache.interned_strings_buffer=16
opcache.max_accelerated_files configures the number of files to be held in memory. A vanilla WordPress website consists of more than 2000 files, not to mention Prestashop, Joomla, Drupal or Magento. Increase this one as high as you think is necessary (and as long as you have physical and virtual memory to spare):
Another interesting setting is
opcache.fast_shutdown. What this actually does is provide a faster mechanism for calling the deconstructors in your code at the end of a single request to speed up the response and recycle php workers so they’re ready for the next incoming request faster.
A fast shutdown sequence relies on the Zend Engine memory manager to deallocate the entire set of request variables en masse.
Turn it on:
Warning: Changing this option is known to cause segfaults under yet to be determined conditions. See the issue #146 on the Opcache repository for more information. We have therefore removed this as a hint.Fine-Tune Your Opcache Configuration to Avoid Caching Suprises – Tideways
Please note that opcache.fast_shutdown is removed in PHP 7.2.0.
Other valuable OPcache settings
Other settings to look at, but are not described in this article, are:
opcache.revalidate_freq. Read the docs to determine how to configure these for yourself.
4 (info messages or debug messages) to temporarily enable OPcache logging. The logfile must be writable by the web server process. But be careful with these settings.
It’s important to go over all OPcache configuration settings. Leaving one untouched, or setting it incorrectly, may open up your server for a new range of attack vectors. A binary webshell through OPcache in PHP 7 is one of them.
Check out Mattias Geniar’s post Mitigating PHP’s long standing issue with OPCache leaking sensitive data and explicity enable the following two settings:
; Validate cached file permissions. opcache.validate_permission=1 ; Prevent name collisions in chroot'ed environment. opcache.validate_root=1
Conclusion PHP OPcache optimization
Tuning OPcache configuration and runtime settings decreases CPU usage on your web server, and may increase memory usage. If done right this’ll speed up your – or your customer’s – websites and PHP throughput.
After making the changes above, and letting Saotn.org run for a little while (little being the operative word…), the OPcache numbers are:
Array ( [opcache_enabled] => 1 [cache_full] => [restart_pending] => [restart_in_progress] => [memory_usage] => Array ( [used_memory] => 33098648 [free_memory] => 17233000 [wasted_memory] => 0 [current_wasted_percentage] => 0 ) [interned_strings_usage] => Array ( [buffer_size] => 8388608 [used_memory] => 4773248 [free_memory] => 3615360 [number_of_strings] => 72659 ) [opcache_statistics] => Array ( [num_cached_scripts] => 801 [num_cached_keys] => 1529 [max_cached_keys] => 7963 [hits] => 947 [start_time] => 1438332765 [last_restart_time] => 0 [oom_restarts] => 0 [hash_restarts] => 0 [manual_restarts] => 0 [misses] => 801 [blacklist_misses] => 0 [blacklist_miss_ratio] => 0 [opcache_hit_rate] => 54.176201372998 )
On a side note: my website also
runs ran WinCache Extension for PHP, as caching back-end in PHP, so these numbers might not reflect your situation. Always test configuration settings in your test- or staging environment before putting it into production.