PHP in version 5.5 comes with a caching engine built-in – OpCache – which stores precompiled script bytecode in the memory. If you’re familiar with APC or Xcache, you will already know how such engines work. As each PHP script is being compiled at runtime, a part of the execution time gets used for transforming the human readable code into code that can be understood by the machine. A bytecode cache engine like OpCache, APC or Xcache does it only once – during the first execution of a specific PHP file. Then the precompiled script is being stored in memory, which should lead to performance boosts in your PHP applications.

Over the web you will easily find a lot of tutorials covering all the OpCache installation and configuration steps (it is enabled by default on 5.5, but can be installed as an extension on older versions). Read the article below to find the answers to some of the typical questions regarding different practical aspects of working with this particular cache engine.

1. Is OpCache worth installing at all? What speed boost can I expect?

Of course, it depends. If your server manages to handle the incoming traffic and keep low response times, you probably won’t feel the need to work on performance. But on a bigger website with a lot of traffic each little optimization step may count. Implementing OpCache may allow you to handle more requests per second and return the response quicker than without a bytecode caching engine. As OpCache is quite easy to install and configure, you won’t spend too much time on setting everything up.

If you’re looking for some OpCache performance tests, you should certainly read the AppDynamics article on implementing this cache engine. In their tests the installation of OpCache reduced the mean response time of a website by 14%. The reduction of response times of different actions of a web application varied from 6% to as much as 74%. As explained in the article, different code parts may benefit more or less from implementing a bytecode caching engine. I encourage you to read the article in detail and check where you can get the highest performance boost.

If you’re looking for some other resources regarding the OpCache performance, check the examples on fideloper.com and massivescale.com. Both tests reported about 50% decrease in response time after installing OpCache.

2. I already use APC cache. Should I migrate to OpCache?

I think you should. There are a couple of advantages that can make OpCache a better solution than APC.

First of all, the APC cache won’t work with the newest PHP versions. It doesn’t support PHP 5.5 at all. It’s not advised to install it on PHP 5.4 either, as it has been reported that such configuration can lead to execution errors that break the whole application. Just check the Wikipedia article on PHP accelerators or this Stack Overflow thread to get some details.

OpCache, however, is bundled with PHP 5.5 so it will definitely work with this PHP version. As written in the documentation, it may also be installed with older PHP versions – from 5.2 to 5.4. Generally, OpCache is more closely bound to PHP itself than other bytecode cache engines – which may result in more frequent updates and fewer errors (read here for details).

The only important thing to remember when migrating from APC to OpCache is the fact that the latter doesn’t work as a data caching engine. If you have already implemented APC, you may be using its apc_add() and apc_fetch() functions which serve as an interface to a data caching service. OpCache is only a bytecode caching engine so it won’t offer a similar functionality. If you’re planning to switch from APC to OpCache, remember to consider this limitation. Keep in mind that if you want to keep APC userland functionality, there’s the APCu project (many thanks to Oscar Merina for pointing it out in the comments).

3. How to check if OpCache is actually caching my files?

If you have already installed and configured OpCache, you may find it important to control which PHP files are actually being cached. The whole cache engine works in the background and is transparent to a visitor or a web developer. In order to check its status, you may use one of the two functions that provide such information: opcache_get_configuration() and opcache_get_status(). Fortunately, there is a couple of prepared scrips that fetch all the OpCache configuration and status data and display it in a friendly way. You don’t need to write any code by yourself, just pick up one of tools from these below:
Opcache Control Panel,
opcache-status by Rasmus Lerdorf,
OpCacheGUI by Pieter Hordijk,
opcache-gui by Andrew Collington.

In my projects I use the opcache-gui script which has all the functionality I need. To check if the caching engine works properly, just look at the percentages at the “Overview” tab at the opcache-gui page. If the memory usage and hit rate values are greater than zero, it means that the OpCache is caching the PHP code and the cached files are being used to handle the requests. To see a list of specific PHP files that are being cached, just navigate to the tab “File usage”. Look through the file list to make sure that the files inside your projects got cached.

4. Is there any framework-specific config that I should set?

Basically, the OpCache engine should be transparent to you as a code writer. It means that you can put any code you want in your application (which works with the PHP version you’re using) and OpCache should handle it properly. But it will work only if the OpCache configuration is set in a correct way. A wrong cache engine configuration can break your entire website.

First of all, probably in each typical project you will have to ensure that the opcache.use_cwd option is set to true. Enabling this setting means that the OpCache engine will look at the full file paths to distinguish between files with the same names. Setting it to false will lead to collisions between files with the same base name.

There is also a setting that is important in tools and frameworks that make use of annotations. If you use Doctrine, Zend Framework 2 or PHP Unit, remember to set the opcache.load_comments and opcache.save_comments settings to true. In result, the documentation comments from your files will also be included in the precompiled code generated by OpCache. This setting will allow you to work with annotations without any disruptions.

If your project is based on a specific framework or a web application, it’s always a good idea to check the documentation for any guidelines regarding the OpCache configuration. For example, there is a sample configuration for Moodle here.

5. I keep my app config in a PHP file. Can I prevent it from being cached?

If your project contains files that are being changed more frequently than the others, you can exclude them from caching. It may be especially handy when dealing with PHP files that contain configuration directives for your website. If you keep them from being cached, you can be sure that each change put in such a file will be visible in your application immediately.

OpCache allows you to specify a blacklist file that contains all the paths that won’t be processed by the caching engine. After setting the opcache.blacklist_filename directive, just put the proper file list in the path you’ve specified. The documentation page contains some examples on how to exclude specific files from cache.

6. How can I run both a development and a production environment on a single server where OpCache is enabled?

If your server runs several apps, you may be willing to use OpCache only in some of them. Development and testing sites are examples of such environments where having bytecode caching enabled is not preferable and can cause more harm than good.

Fortunately, it is possible to have OpCache enabled in one project and disabled in another, all on a single server. To do so, first you need to enable the OpCache at the global level by setting the opcache.enable directive to true in your php.ini file. Then, if you don’t want to use bytecode caching in one of your projects, just disable it by setting the same directive to false using the ini_set() function. So first you need to enable the caching globally and then you can disable it in some projects “locally”. You can’t do the opposite – enabling caching using ini_set() is not allowed.

Setting opcache.enable to false in a top file in your project will disable the caching while keeping it on elsewhere.

Summary

I hope this set of common questions and answers gave you some practical information on how to use OpCache in a PHP application. If you have other questions or comments regarding the subject, feel free to post them below. You can also contact me through Google Plus.

Jacek is a web developer specialized in building extensive web applications, mainly e-commerce solutions. The technologies he uses on a daily basis include PHP, MySQL, HTML+CSS and JS+jQuery. During the last few years he was the head developer of a highly customized online store platform in Poland. Now he's working on the development of several e-commerce websites running in Poland and Germany, often having hundreds of thousands pageviews a day. To take a break from coding, he does challenging crossfit workouts, goes out to taste some new food or dives into an interesting psychology magazine or book.

Get your free chapter of Level Up Your Web Apps with Go

Get a free chapter of Level Up Your Web Apps with Go, plus updates and exclusive offers from SitePoint.


  • omerida

    Article should mention if you need to keep APC’s userland caching functions, there is the APCu project: http://pecl.php.net/package/APCu

    • http://www.bitfalls.com/ Bruno Skvorc

      Indeed, thanks for pointing it out

  • http://www.drlinux.no/ Arne K. Haaje

    Doesn’t this only work with mod_php, and not fast-CGI etc. due to caching being in shared memory? That will make it unusable to many shared hosters, which could use it the most for reducing server load.

    Regarding server load, an opcache does wonders for any server running a large application. If you run any framework, Joomla, WordPress, Magento or other large application, then you really should use an opcache if you have any kind of traffic.

  • http://open-classifieds.com/ Chema

    Here some tips about which php5.5 zend optimizer settings to use

    http://garridodiaz.com/php5-5-zend-optimizer-settings-use/

  • http://www.saotn.org JanR

    For web servers running Windows Server IIS, you can still use the Windows Cache Extension (WinCache) with PHP 5.5+. Except not with the opcode cache portion of Wincache of course, which is now deprecated in favor of OPCache.

  • Tatsh

    I use uWSGI for all my PHP apps now (with PHP embedded). You need at least uWSGI 2.0.6 version to have this option in your application configuration:

    [uwsgi]
    plugins = php55
    php-sapi-name = apache

    The reason is because OpCache is stupidly hard-coded to only work with Apache, CLI, and FPM. I’ve been running with this ‘hack’ for months (ran it on a patched uWSGI before 2.0.6 was released).

    Speed vs PHP-FPM is probably about the same. But I see a little less memory usage with uWSGI and a lot more tuning options, like `cheaper-initial`.

  • P.K. Hunter

    We already use Zend Optimizer and eAccelerator on our platform. Will OpCache help further?

  • http://josephscott.org/ Joseph Scott

    The only important thing to remember when migrating from APC to OpCache is the fact that the latter doesn’t work as a data caching engine.

    I’d say that APC using inodes for cache references and OpCache using the file path is another major thing that you need to plan for when switching.

    • David

      Not sure if it’s related to file paths/inodes, but I’ve noticed that OpCache won’t detect file changes when you have FPM running with chroot.

    • http://pinoyrooms.com/ pinoy rooms

      If I use OpCache, can I use it for multiple websites ? Will it have mixture of cache from websites?

      For APC, I can set individual file mask path to each website.

  • Shaquille Yang

    great artitle!

Related books & courses
Jump Start MySQL

Available on SitePoint Premium. Check it out now!