The PHP stat cache explained

90% of the time when I explain how the stat cache works in PHP, people are surprised because they expected it to work differently. It was invented to solve a very limited problem when you call several file system related operations on the same file in quick succession.

Why should you know how it works? Because sometimes you need to work around the cache with the clearstatcache() function to get PHP code to run without errors.

Historical Context

Let us start at the beginning. What is stat? It is a C-level API call to the filesystem to query the metadata of a file, such as user, group, readability, writability, size, modification times. And PHP wraps this call with its own function that is also called stat and also uses this function internally in different places.

Historically, this has been an expensive operation to perform.

A number of PHP functions need this, PHP’s stat itself of course, but also file_exists, is_readable, is_writable and many more.

PHP’s stat cache

That is where the PHP stat cache comes into play: It caches the result of low-level stat operations. With one important caveat. The cache only caches this information for exactly one file. The last one that used the cache. And it caches this on the request-level, it is not a cross-request or process cache like OPcache.

This means that if PHP performs a low-level stat operation on a file and it wasn’t in the stat cache before, it will overwrite the previously stored stat data for the previous file.

How is the stat cache implemented?

If the stat cache were to be implemented in PHP, it would look something like this:

<?php
class FileStat
{
    private static string $CurrentStatFile;
    private static PhpStreamStatBuffer $ssd;

    public function stat(string $path)
    {
        if ($path === self::$CurrentStatFile) {
            return self::$ssd;
        }

        $statBuffer = new PhpStreamStatBuffer(stat($path));
        self::$CurrentStatFile = $path;
        self::$ssd = $statBuffer;

        return $statBuffer;
    }
}

You can find this code in “ext/standard/filestat.c” in “php_stat” function.

Conclusion

So what does this tell us about the stat cache? Is it useful? It is hard to tell, especially on modern Linux and with SSD disks. But I didn’t measure, a topic for future research.

But if you want to make use of it, remember that you cannot interleave operations on multiple files, they would cause the cache to be overwritten.

You’ll find the complete list of functions that use the stat-cache in the documentation of the clearstatcache() function.

Benjamin Benjamin 14.08.2023