PHP Benchmarks: OPcache vs OPcache w/ Performance Tweaks

A few weeks ago I wrote a short article which highlighted GUI solutions for monitoring and controlling PHP OPcache. We all know that enabling PHP OPcache provides massive performances gains (see benchmark graph at the end of article). In addition, since PHP 5.5, OPcache is now enabled by default. With these facts in mind, is it possible to squeeze a little more performance out of PHP by tweaking OPcache’s directives? This is what I’ll set out to answer.

Benchmarking PHP: Default OPcache vs OPcache + Tweaks

Today, I ran a few quick benchmarks capturing the 2nd run data of tests. First on a 32GB/16 cpu core VPS (Ubuntu 16.04 LTS), which resulted in the below PHP7 + OPcache vs PHP7 + OPcache + Tweaks benchmark graph using Apache Bench (ab):

PHP Benchmarks: OPcache Performance Tweaks

Next, I also tested with a 1GB/1 cpu core VPS, the 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 as well. So I changed the default mpm_prefork to mpm_event (more about mpm_event: Strip Down Apache to Improve Performance & Memory Efficiency) and swapped out 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 may be happy to take whatever improvements you can find. Also, this test was with Wordpress only, with other PHP web apps and scripts these results could result in even more performance gains, or less… you can read the following config options and be the judge. Share your sweet-spot settings and/or advise for OPcache.

Related:  OpenSSL Security Updates - Severity: High

opcache.validate_timestamps=0

(enabled by default “1”)If enabled, OPcache will check for updated scripts every opcache.revalidate_freq=# of seconds. When disabled, opcache.revalidate_freq  is ignored and you must reset OPcache manually via opcache_reset(), opcache_invalidate() or by restarting PHP for changes to the filesystem to take effect.

So by default OPcache tries to be as developer friendly as possible with time stamps to validate cached files. However, this convenience comes at the cost of performance as it does add operational overhead. For many production servers, especially when you have a separate development server, this directive can be safely disabled. If you need to keep it enabled, see the end of this post regarding 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 files that are less than this number of seconds old. It protects from caching of incompletely updated files. In case all file updates on your site are atomic, you may increase performance setting it to “0”. Documentation is limited.

opcache.fast_shutdown=1

Fast shutdown attempts to use a faster mechanism for clearing memory. If enabled, a fast shutdown sequence is used that doesn’t free each allocated block, but instead relies on the Zend Engine memory manager to deallocate the entire set of request variables in mass. Use this with PHP7+, may experience segfaults with older versions of PHP.

Related:  Linux - How to Securely Copy Files Using SCP examples

Here’s a copy of the config (opcache.ini) that was 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 http://localhost/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

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 are wondering why all the the fuss about PHP Opcache, here’s a benchmark of PHP 7 without OPcache vs PHP 7  +OPcache (concurrency lowered to 2 because without opcache PHP fails 90% of requests).

Related:  'Clean' upgrade to PHP 7.* (CentOS / Debian / Ubuntu)

PHP 7 without OPcache vs PHP 7 +OPcache

References: Apache Bench, PHPPHP OPcache.

Tags: , ,

36 Shares
Tweet
Share
Share
+1
Reddit