How To Clear PHP’s Opcache

Mattias Geniar, Wednesday, August 5, 2015 - last modified: Saturday, August 8, 2015

PHP can be configured to store precompiled bytecode in shared memory, called Opcache. It prevents the loading and parsing of PHP scripts on every request. This guide will tell you how to flush that bytecode Opcache, should you need it.

You may want to flush the APC (PHP < 5.5) or Opcache (PHP >= 5.5) in PHP when it has cached code you want to refresh. As of PHP 5.5, the APC cache has been replaced by Opcache and APC only exists as a user key/value cache, no longer a bytecode cache.

Determine your PHP method

You can run PHP in multiple ways. The last few years, PHP has evolved into new methods, ranging from CGI to FastCGI to mod_php and PHP-FPM. Flushing your Opcache depends on how you run PHP.

If you want a uniform way of flushing your Opcache, you can create a PHP file called flush_cache.php in your docroot with content like this.

<?php
opcache_reset();
?>

Every time you want to flush your Opcache, you can browse to that file and it'll call opcache_reset(); for your entire Opcache. The next PHP request to your site will populate the cache again.

It's important that you call that URL in the same way you would reach your website, either via a HTTP:// or HTTPS:// URL. Running php flush_cache.php at the command line won't flush the cache of your running processes.

This can be part of your deployment process, where after each deploy you curl that particular URL.

If you want a server-side solution, check further.

PHP running as CGI or FastCGI

Flushing the Opcache on CGI or FastCGI PHP is super simple: it can't be done.

Not because you can't flush the cache, but because the cache is flushed on every request anyway. FastCGI starts a new php-cgi process on every request and does not have a parent PHP process to store the Opcache results in.

In fact, having Opcache running in a CGI or FastCGI model would hurt performance: on every request the Opcache is stored in the FastCGI process (default behaviour if the Opcache extension activated), but that cache is destroyed as soon as that process dies after finishing the request.

Storing the Opcache takes a few CPU cycles and is an effort that cannot be benefited from again later.

CGI or FastCGI is about the worst possible way to run your PHP code.

PHP running at the CLI

All PHP you run at the command line has no Opcache. It can be enabled, and PHP can attempt to store its Opcache in memory, but as soon as your CLI command ends, the cache is gone as well.

To clear the Opcache on CLI, just restart your PHP command. It's usually as simple as CTRL+C to abort the command and start it again.

For the same reason as running PHP as CGI or FastCGI above, having Opcache enabled for CLI requests would hurt performance more than you would gain benefits from it.

Apache running as mod_php

If you run Apache, you can run PHP by embedding a module inside your Apache webserver. By default, PHP is executed as the same user your Apache webserver is running.

To flush the Opcache in a mod_php scenarion, you can either reload or restart your Apache webserver.

$ service httpd reload
$ apachectl graceful

A reload should be sufficient as it will clear the Opcache in PHP. A restart will also work, but is more invasive as it kills all active HTTP connections.

PHP running as PHP-FPM

If you run your PHP as PHP-FPM, you can send a reload to your PHP-FPM daemon. The reload will flush the Opcache and force it to be rebuilt on the first incoming request.

$ service php-fpm reload

If you are running multiple PHP master, you can reload a single master to only reset that masters' Opcache. By default, it will flush the entire cache, no matter how many websites you have running.

If you want more control at the command line, you can use a tool like cachetool that can connect to your PHP-FPM socket and send it commands, the same way a webserver would.

First, download the phar that you can use to manipulate the cache.

$ curl -sO http://gordalina.github.io/cachetool/downloads/cachetool.phar

Next, use that phar to send commands to your PHP-FPM daemon.

$ php cachetool.phar opcache:reset --fcgi=127.0.0.1:9000
$ php cachetool.phar opcache:reset --fcgi=/var/run/php5-fpm.sock

Using something like cachetool can also be easily integrated in your automated deploy process.



Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek & public speaker. Currently working on DNS Spy & Oh Dear!. Follow me on Twitter as @mattiasgeniar.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!

Comments

Johnny Robeson Wednesday, August 5, 2015 at 22:40 - Reply

cachetool doesn’t work by default with SELinux enabled. I’ve been meaning to attempt to build a policy for it, but haven’t gotten around to reading the proper docs yet.


Maciej Iwanowski Friday, December 4, 2015 at 12:16 - Reply

Mattias, I have been running PHP-FPM for couple of years and I have been using opcache since it 5.5.0 was released. It *is* possible to use fastcgi and opcache in the same time and it comes with huge performance improvement. I do believe that you should update your post as it is misguiding PHP users at the moment.


Blaise Tuesday, May 24, 2016 at 11:21 - Reply

Great post! This is the first time that someone clearly states that fast CGI and opcache do not work well together!
I spent hours trying to make this work and I noticed indeed that the opcache was cleared every few seconds with the start time modified at each restart.
I tried running with PHP FPM instead (and nginx) but this creates a lot of problems on my site. So I’m stuck with fast CGI and no opcache.
Now if someone can tell my how to keep a persistent opcache with fastCGI I would be really happy!


Thomas Friday, August 5, 2016 at 17:01 - Reply

“In fact, having Opcache running in a CGI or FastCGI model would hurt performance: on every request the Opcache is stored in the FastCGI process (default behaviour if the Opcache extension activated), but that cache is destroyed as soon as that process dies after finishing the request.”

That is plain and simple wrong! The benefit of FastCGI (over plain CGI) is that the CGI processes keep running in the background – even if the initial request has been finished. Those processes will be idling in the background until new requests come in and the FCGI supervisor will send those requests to available FCGI processes in the background. As a consequence, your OpCache data won’t be cleared/destroyed on every new request like you stated (This is true for plain CGI, but not for FastCGI setups).

“CGI or FastCGI is about the worst possible way to run your PHP code.”

This is also wrong – the performance of FastCGI is often comparable to that of PHP-FPM. Plain CGI on the other hand has terrible performance, since for every incoming request a process has to be fork()ed in the background.


Chandra Kishor Thursday, September 29, 2016 at 08:54 - Reply

I agree with Thomos and realized after Benchmark. Thanks Thomos!
If someone is telling that opcache will hurt in Fast-CGI environment, Please let us know the detail.


Carlos Saturday, October 22, 2016 at 00:28 - Reply

Is there an option to re-cache all files on a specific dir ?
Let’ say, scan /var/www and cache all files.

Thanks.


Maurice Tuesday, February 28, 2017 at 11:49 - Reply

Hi Matthias, just read thru your post and thanks for sharing this information.

You say that “FastCGI model would hurt performance”. This is completely wrong. FastCGI is the way to go if you need performance and it’s exactly what PHP FPM does. FPM stands for FastCGI Process Manager and uses the FastCGI protocol; it “just” adds dynamic process spawning and things like that.


Mike Kormendy Tuesday, April 11, 2017 at 03:37 - Reply

This article is wrong on so many levels. Readers beware.


William Marchand Thursday, September 28, 2017 at 18:42 - Reply

Thanks but won’t restarting apache has the same effect


Ogier Schelvis Monday, December 4, 2017 at 11:49 - Reply

This cachetool utility is awesome! Thanks! Very graceful.


Kristian Monday, January 29, 2018 at 12:24 - Reply

In what situations would you need to clear the entire opcache? From the documentation, it seems to me that changes to individual files would be picked up within the time defined by opcache.revalidate_freq (default 2 seconds), assuming opcache.validate_timestamps is enabled (which it is by default), and then a full opcache reset should not be necessary.


    Mattias Geniar Monday, January 29, 2018 at 12:34 - Reply

    From the documentation, it seems to me that changes to individual files would be picked up within the time defined by opcache.revalidate_freq (default 2 seconds)

    Yup, this is only needed in cases where you want maximum performance by eliminating all PHP disk I/O. If you enable opcache.validate_timestamps, it’ll still have to check (all) your PHP files for updated timestamps. If you control your deploy mechanisme, there’s no need to every have that setting on, as all changes can be followed by an OPCache flush.

    So why bother? Performance, mainly. Makes everything run smoother, less disk I/O, happier clients. :-)


Leave a Reply

Your email address will not be published. Required fields are marked *

Inbound links