How to optimize PHP OPcache configuration

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.

Wondering how 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.
; The amount of memory for interned strings in Mbytes.
; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 100000 are allowed.
; If enabled, a fast shutdown sequence is used for the accelerated code

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

I thought you might find this interesting:   phpinfo() Type Confusion Infoleak Vulnerability and SSL Private Keys

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:


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

I thought you might find this interesting:   How to enable HTTP Strict-Transport-Security (HSTS) on IIS

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. Please note that this directive 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.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 run for a little while (little being the operative word…), the OPcache numbers are:

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

I thought you might find this interesting:   Clean up WordPress post revisions

Please Support

Each post on Sysadmins of the North takes a significant amount of time to research, write, and edit. Therefore, your donation helps a lot! For example, a donation of $3 U.S. buys me a cup of coffee, and as you know: things jsut work better with coffee. A $10 U.S. donation buys me one month of web hosting (yes, hosting costs money). But seriously, thank you for any amount. Much appreciated!

Please donate to support this site if you found a post interesting or if it helped you solve a problem. Thanks! (Tip: no Paypal account required)

If you appreciated this post, then please donate using this Paypal button

Jan Reilink

My name is Jan. I am not a hacker, coder, developer, programmer or guru. I am merely a system administrator, doing my daily thing at Vevida in the Netherlands. With over 15 years of experience, my specialties include Windows Server, IIS, Linux (CentOS, Debian), security, PHP, websites & optimization.

Leave a Reply

2 Comments on "How to optimize PHP OPcache configuration"

Hi! Join the discussion, leave a reply!

Sort by:   newest | oldest | most voted
Luke Cavanagh

Awesome post, thank you for sharing!