PHP OPcache Quick Reference

PHP OPcache Quick Reference

OPcache is a feature of the PHP runtime that is often overlooked by developers/teams when deploying PHP applications. Many competent PHP developers are not aware of the benefits of enabling OPcache in their PHP applications. I understand that it’s a hassle to look at the finer points of your php-fpm config but it is worth having an understanding of what OPcache is and how it can help you.

In general you only need two config sets for OPcache, one for development and one for production. I will provide examples of these below.

Table of Contents

Open Table of Contents

What Is OPcache?

The main purpose of OPcache is to improve PHP performance by storing precompiled script bytecode in shared memory. This eliminates the need for PHP to load and parse scripts on each request.

A Brief History

  • PHP OPcache is a bytecode cache that was introduced in PHP 5.5 in 2013. It replaces the previous opcode caching mechanism in PHP.
  • Development of OPcache began in 2008 under the name “PHP Next Generation” (PHPNG). The goal was to overhaul PHP’s bytecode caching and compilation process.
  • In 2011, work on PHPNG was merged into the PHP core and it was renamed to OPcache. Dmitry Stogov was the primary developer behind OPcache.
  • When OPcache was integrated into PHP 5.5, it provided up to 50% faster performance for PHP applications. This allowed PHP to catch up to other languages in terms of performance.
  • Over the years, OPcache has continued to receive performance improvements and bug fixes. It gained file-based caching in PHP 5.5, optimization for short-lived scripts in PHP 7, and preloading support in PHP 7.4.

Advantages

  • Server performance improvements due to:
    • Reduced disk I/O
    • Reduced CPU usage
  • Faster response time
  • Ability to handle more traffic with the same resources

Disadvantages

  • You need to spend time learning about the optimal configuration for your application
  • You need to monitor it to ensure it’s working as expected
  • If it’s misconfigured, it could affect performance negatively

How to enable it

OPcache must be installed and enabled to use it. Here are some basic instructions for installing and enabling OPcache. They are not exhaustive.

Installing OPcache

Debian/Ubuntu

Install the php-opcache package.

RedHat/CentOS/Amazon Linux/Fedora

Install the php-opcache package.

In Docker

 docker-php-ext-install OPcache

Compiling from source

If compiling PHP from source, specify --enable-opcache when running ./configure.

Enabling OPcache

General

Add (or uncomment) the following in your php.ini file:

[opcache]
opcache.enable=1

More specifically, you should make a file called opcache.ini and add it to your conf.d directory. Typically this is located at /usr/local/etc/php/conf.d/ or /etc/php/conf.d but your system may vary.

In Docker

RUN docker-php-ext-enable OPcache

How do I know if it’s installed?

There are multiple ways to check if OPcache is installed and ready to use.

Command line

First of all, check that the module is loaded:

php -m | grep opcache

Then check that the config is available:

php -i | grep opcache

To see more detailed information about OPcache’s configuration, run the following command:

php -r 'print_r(opcache_get_configuration());'

Using phpinfo()

Another good way to check if OPcache is available is to use the phpinfo() function.

Add a file (e.g. info.php) containing the following code to your web server, in the app’s root directory (normally where your index.php file is located):

<?php
phpinfo();

Open the file in your browser (e.g. http://localhost/info.php) and search for “opcache” on the page. If you see a section called “Zend OPcache” then OPcache is working.

Don’t forget to remove this file when done!

How do I know if it’s working?

Once we’ve checked that it’s available, we need to see that it’s actually working. OPcache maintains statistics about the cache which we can use to check if it’s working.

php-fpm

If you’re using php-fpm, you can use the opcache_get_status() function to get the status of the cache. Typically you would put this in a file in your app’s root directory (e.g. status.php) and then open it in your browser.

<?php

print_r(opcache_get_status());

To secure this file you may like to configure your webserver to only access from localhost or you can use $_SERVER['REMOTE_ADDR'] to check this within the actual script. You can also use opcache.restrict_api = /status.php in your config to restrict access to this file.

When accessing this URL, you’ll see a large array of information about the cache.

You’re looking for the following:

  • num_cached_scripts > 0
  • Paths showing in scripts

The creator of PHP, Rasmus Lerdorf, created a script to parse and display this output in a more human readable format. You can find it here

It was updated 9 years ago! So you may need to make some changes to get it working. There are also forks that may help.

OPcacheGui is another option.

These are only for simple use cases. When running an application in production, a suitable way to get this information is to use a tool such as Datadog, specifically their PHP OPcache agent integration. Once you have installed and configured this, you can create a dashboard within Datadog to view the metrics you care about.

Command line

If you’ve set opcache.enable_cli=1 in your config, it will be available for use on the command line.

In this case you can run the following command to see the status:

php -r 'print_r(opcache_get_status());'

This will output an array of information about the cache.

CLI usage is not included in this article yet, as it is not a common use case.

Contact us if you need help with using OPcache with the PHP CLI.

Suggested Monitoring Metrics

OPcache is not hard to use but it should be monitored. In particular, you need to monitor its memory usage. In practice this means monitoring the following metrics:

  • Enablement of the cache_full value
    • This will indicate that the cache was filled up and may trigger a reset
    • If this is happening frequently, you may need to increase memory_consumption
  • free_memory
    • If free_memory is close to 0, you may need to increase memory_consumption
  • memory_consumption vs max_memory_consumption
    • If memory_consumption is close to max_memory_consumption then you may need to increase memory_consumption
  • num_cached_keys vs max_cached_keys
    • If num_cached_keys is close to max_cached_keys then you may need to increase max_accelerated_files
  • opcache_hit_rate
    • Hit rate will generally be high, so set a threshold below 90% to alert on as it may indicate a problem with configuration or a security breach
  • oom_restarts and hash_restarts and last_restart_time
    • OPcache will perform restarts if it runs out of memory, or if the percentage of wasted memory exceeds opcache.max_wasted_percentage

This is just a quick summary of some of the things to monitor. There are many permutations of OPcache configuration, which means there are many different ways to set up effective monitoring. If you need help with this, contact us.

Sample Configurations

The following are just sample configurations. They need to be modified for your environment.

Development

[opcache]
opcache.enable=1
opcache.revalidate_freq=0
opcache.validate_timestamps=1
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.max_wasted_percentage=5
opcache.interned_strings_buffer=8
opcache.file_update_protection=1

Production

Notes

In production we disable opcache.validate_timestamps because we don’t want to check the file timestamps on every request. This means that when you deploy updates that include changes to your PHP files, you will need to reload or restart your PHP-FPM service. If this is not an option, you can also use the opcache_reset() function to clear the entire cache or opcache_invalidate() to clear a single file from the cache. Note this needs to be run by a php-fpm worker process otherwise it will apply to the CLI cache.

If you’re not using containers, this will need to be an additional step in your deployment process.

There are tools such as cachetool which can make it easy to achieve the above.

Config

The following config assumes:

  • your deployment process handles reloading the cache
  • a dedicated server or container is being used, use_cwd should be enabled otherwise
[opcache]
opcache.enable=1
opcache.validate_timestamps=0
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.max_wasted_percentage=5
opcache.interned_strings_buffer=16
opcache.use_cwd=0

Need Help?

Is your PHP application running slowly? Is your team too busy to look into it? We can help. Book a call and we’ll explain how we can help.

cta-image

See How We Can Help Your Team Deliver More Value, Faster

  • Quality: Get expert code reviews
  • Clarity: Get expert advice on your backlog, architecture, and hosting
  • Help: Get unblocked quickly with our expert support

Get Started

Related Posts