Cache Information Upgrade
A reminder of the different cache information Blackfire provides, with a few recent improvements.
Blackfire gives you visibility on how your application behaves. However, the interaction between functions is not the only thing that could affect your application performance.
Your app indeed usually runs over an engine based on the language you use (e.g. PHP, Python…), which can also be fine-tuned to provide the best possible performance, especially when it comes to internal cache mechanisms.
PHP Caches and their Purposes
PHP has a collection of internal cache mechanisms which serves different purposes. Some are purely internal and other are provided by extensions.
Realpath cache
In this cache, PHP stores the full path to the files your application uses. Keeping these locations in cache avoids multiple expensive lookups (i.e. stat
calls) to the filesystem. The default value is 4M as of PHP 7.0.16, which is usually more than enough.
It is configurable with the realpath_cache_size
setting in php.ini
PCRE cache
This cache keeps regular expressions in memory, in order to avoid evaluating them.
This cache is not configurable.
APCu
This PHP extension provides a key/value store within the PHP engine itself. It can be used for application cache (e.g. using Symfony Cache Component), or to optimize Composer autoloader.
OPCache
This PHP extension, which is part of the core as of PHP 5.5, optimizes and caches opcode generated by PHP. It is always recommended to have it enabled, and mandatory for production servers. Putting it simple, it avoids recompiling PHP files by caching the result in a shared memory (aka shm
).
It also provides a few candies 🍬 like the Interned Strings Buffer.
Behind this cryptic name lies a fundamental and powerful cache, as in this buffer, OPCache stores every immutable strings of your application (including annotation comments), and that makes a lot of strings!
Each string is linked to a pointer, which is then reused whenever possible.
Actually, the Interned Strings mechanism has been there for a long time in PHP (since PHP 5.4.0), but the pointers were not shared between processes. OPCache adds a buffer over it, so that the pointers can be shared between PHP-FPM workers.
Learn more about Interned Strings Buffer in the awesome article by Julien Pauli.
Blackfire Providing Cache Information
In every profile, Blackfire provides a summary of all these caches. Always keep an eye on those level gauges and ensure to dimension them enough. We usually consider that a cache buffer should be filled up more than 85%.
Recent Improvements with OPCache
In some cases, OPCache can lead to unexpected behaviors, leading to very slow requests. This is usually due to the OPCache restart mechanism, and means that you should tweak your configuration.
OPCache shared memory consumption should not grow that much when it is well dimensioned. However when a script changes OPCache doesn’t free the buffer. It marks the stale script as wasted. This happens because of the recompilation of the modified PHP files, e.g. when you deployed new ones, or because your application has generated other PHP files.
In such cases OPCache can restart in order to purge its shared memory. The problem is that it can be very costly in terms of resources consumption, and thus performance!
To avoid confusions, we recently added information about OPCache restarts:
It usually happens when OPCache runs out of shared memory. Rule of thumb: Never run out of OPCache shared memory!
Remember that whenever you change files, OPCache will recompile them and mark the previous ones as /wasted/, making the shared memory grow.
At some point, defined by the opcache.max_wasted_percentage
setting, OPCache will restart.
To avoid this, we recommend to follow the suggestions made by Julien in his article:
- Turn off revalidation mechanism on production (turn
opcache.validate_timestamps
to0
) - Correctly size your buffers (
opcache.memory_consumption
,opcache.interned_strings_buffer
,opcache.max_accelerated_files
Play with the demo or subscribe now!
Happy profiling, but keep an eye on Cache Information 😉!