Patrick Kerrigan

PHP Opcache file cache

by Patrick Kerrigan, . Tags: Php Web Performance

Opcache is one of PHP's most powerful tools when it comes to performance. With the release of PHP 7 it received a new feature which has gone largely un-noticed: the file cache. Depending on your hosting environment and/or traffic levels the file cache may be able to help squeeze even more performance out of PHP.

Understanding Opcache

PHP generally operates with a shared-nothing execution model. For every request that hits your web app PHP will read, parse, compile and run the app's code before throwing all of this work away to be done again for the next request.

With Opcache enabled, PHP can jump straight to the execution of your code. On the first request, the code is read, parsed and compiled. This compiled code (PHP opcodes) is then kept in memory so that these steps don't need to be repeated for the next request. On the next request, PHP just loads the compiled code from memory and executes it, leading to a huge boost in performance.

For more information on setting up Opcache, see my previous post on PHP performance tuning.

Where Opcache falls short

There are still a few situations where Opcache won't be able to work as effectively as it should. As the compiled code is kept in memory it gets wiped out when the PHP process is restarted or the cache is cleared. There are many causes for this, such as upgrading PHP or the underlying server, deployments, shared hosting environments that shut down your PHP process after inactivity and more.

In the best case, requests hitting a cold cache will result in a slow initial pageload. In the worst case, such as for high traffic web apps, it can result in extremely high CPU usage as many simultaneous requests all attempt to populate the cache.

File cache - a persistent opcode cache

If you're running PHP 7 or above, Opcache now has a built in file based cache. This allows PHP to store compiled code both in memory for fast execution, and on disk for situations when the memory gets flushed. This still allows it to skip the parsing and compilation steps when executing the initial requests in a freshly restarted environment.

To enable the file cache, create a directory outside of your document root such as /home/www/opcache (assuming the PHP process runs as the "www" user in this case) and set this as the value of "opcache.file_cache" in php.ini. It's important that this direcotry is writable by the PHP user.

opcache.file_cache = "/home/www/opcache"

Restart PHP, and if everything is working you should start to see files appear in this directory with a ".php.bin" extension after you load your first page. You can also try restarting your PHP process and should notice a considerable difference in page load times after the restart.

Security implications

You may have noticed that this requires the PHP user to have write access to the file cache directory. This means that if your application is vulnerable to unrestricted file uploads then somebody could upload a pre-compiled PHP script to the file cache directory and run it. Keep this in mind when deciding whether or not you want to make use of this feature.