PHP Benchmark: OPcache vs OPcache w/ performance changes

A few weeks ago, I wrote a short article highlighting GUI solutions for monitoring and controlling PHP OPcache. We all know that enabling PHP OPcache provides massive performance gains (see the benchmark graph at the end of the article). Also, since PHP 5.5, OPcache is now enabled by default. With these facts in mind, is it possible to extract a bit more performance from PHP by modifying the OPcache directives? That’s what I am ready to answer.

Benchmarking PHP: Default OPcache vs OPcache + Tweaks

Today, I ran some quick benchmarks capturing second run data of the tests. First, on a 32GB/16 CPU core VPS (Ubuntu 16.04 LTS), resulting in the below PHP7 + OPcache vs PHP7 + OPcache + Tweaks Benchmark graph using Apache Bench (AB):

After this, I also tested with 1GB/1 CPU core VPS, result:

Same benchmark on 1GB/1 cpu core VPS

Also, although OPcache works regardless of the PHP handler used, I wanted to make sure the results were the same with PHP-FPM. so i changed the default mpm_prefork to mpm_event (More about mpm_event: Stripping Apache to Improve Performance and Memory Efficiency) and swap mod_PHP for PHP-FPM On the same 1GB/1 CPU core VPS:

Benchmark with PHP-FPM

These are not mind blowing results. However, depending on your current throughput of PHP requests, you might be happy to take whatever improvements you can find. Also, this test was with WordPress only; As with other PHP web apps and scripts, these results can result in even greater performance gains, or less… You can read the following configuration options and be the judge. Share your sweet-spot settings and advice for OPcache.

opcache.validate_timestamps=0

When enabled (“1” by default), OPcache will check each update script opcache.revalidate_freq=# of seconds. when disabled, opcache.revalidate_freq are ignored, and you must manually reset OPcache by opcache_reset(), opcache_invalidate(), or restarting PHP for the changes to the file system to take effect.

So by default, OPcache tries to be as developer-friendly as possible with the timestamps for validating cached files. However, this convenience comes at the cost of performance as it adds to the operational overhead. For multiple production servers, especially when you have a separate development server, this directive can be safely disabled.

If you need to keep it enabled, watch the end of it this post In regards to increasing the time between checks from 2 seconds to maybe 10 or more, depending on what you can live with.

opcache.file_update_protection=0

(default “2”) prevents caching of files older than this second. This avoids caching of incompletely updated files. You can increase the performance by setting it to “0”. documentation is limited,

opcache.fast_shutdown=1

Fast shutdown tries to use a faster mechanism to clean up memory. If enabled, an immediate shutdown sequence is used that does not free each allocated block. Instead, it largely relies on the Zend Engine memory manager to remove the entire set of request variables. Use it with PHP7+. You may experience segfaults with older versions of PHP.

PHP 8 performance tips.

Also, see PHP 8 compatibility checks and performance tips.

Here is a copy of the config (opcache.ini) that I used…

Default PHP OPcache:

zend_extension=opcache.so

PHP OPcache+ Tweaks:

zend_extension=opcache.so
opcache.fast_shutdown=1
opcache.file_update_protection=0
opcache.validate_timestamps=0
opcache.interned_strings_buffer=16

Example command:

ab -n 1000 -c 20 -g opcache_yes.dat 
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, 
Licensed to The Apache Software Foundation, 

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software: Apache/2.4.18
Server Hostname: localhost
Server Port: 80

Document Path: /
Document Length: 51919 bytes

Concurrency Level: 20
Time taken for tests: 1.815 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 52154000 bytes
HTML transferred: 51919000 bytes
Requests per second: 551.08 [#/sec] (mean)
Time per request: 36.292 [ms] (mean)
Time per request: 1.815 [ms] (mean, across all concurrent requests)
Transfer rate: 28067.40 [Kbytes/sec] received

Connection Times (ms)
 min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 19 36 5.6 35 66
Waiting: 17 33 5.4 33 62
Total: 19 36 5.6 35 66

Percentage of the requests served within a certain time (ms)
 50% 35
 66% 37
 75% 39
 80% 40
 90% 43
 95% 46
 98% 51
 99% 53
 100% 66 (longest request)

If you’re wondering why all the fuss about PHP Opcache, here’s a benchmark PHP 7 without OPcache vs PHP 7 +OPcache (concurrency is reduced to 2, because without OPcache, PHP fails 90% of requests).

PHP 7 without OPcache vs PHP 7 +OPcache

References: Apache Bench, PHP, PHP Opcache,
Originally Published: October 3, 2017 | Last Updated: May 12, 2021

Leave a Comment