Optimize PHP’s OPcache configuration

Reading Time: 6 Minutes
It's only fair to share...
Share on Facebook8Tweet about this on TwitterShare on LinkedInShare on Google+2

Tune OPcache and make PHP OPcache perform even better! Now that you have optimized your PHP realpath_cache_size configuration, it is 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…

Advertisement:

PHP OPcache opcode cache #

PHP OPcache is an opcode cache: OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request. This allows PHP to use the precompiled bytecode instead of compiling it on every request. This extension is bundled with PHP 5.5.0 and later.

Looking to flush OPcache?

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.

Related:   How to install Microsoft's SQL Server Driver for PHP

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:

opcache.memory_consumption=48

The 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:

opcache.interned_strings_buffer=8

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):

opcache.max_accelerated_files=5000

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: opcache.fast_shutdown=1

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

I’ve seen these segfaults with PHP 5.6 and OPcache, but not with PHP 7 and OPcache. Set opcache.fast_shutdown to 0 or 1 depending on your set-up.

Related:   Ghost on IIS with HTTPS, how to resolve a "Too many redirects" error

Other valuable OPcache settings #

Other settings to look at, but are not described in this article, are: opcache.validate_timestamps and opcache.revalidate_freq. Read the docs to determine how to configure these for yourself. Set opcache.error_log=/path/to/your/logfile and opcache.log_verbosity_level=3 or 4 (info messages or debug messages) to temporarily enable OPcache logging. The logfile must be writable by the web server process.

OPcache security #

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.

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 WinCache 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.

Related:   PowerShell Get-FsrmQuota and Set-FsrmQuota

It's only fair to share...
Share on Facebook8Tweet about this on TwitterShare on LinkedInShare on Google+2

Advertisement:

2 Replies to “Optimize PHP’s OPcache configuration”

Hi! Join the discussion, leave a reply!