Setting PHP variables should not be a blind search upon which you just set what a guide recommends. If you search about realpath_cache_size and realpath_cache_ttl, you’ll find various recommendations.
Just a reminder: the realpath cache, helps with finding… you guessed it! The realpath, directory or file status of a file. Even when the accesed file is not a symlink.
It really makes sense to always store entries, because we can avoid a file I/O call this way. Now on to setting it properly.
But how can you tell if you should have 128K, 512K, 1M or even 4M as realpath_cache_size?
Easy! Just check how much memory does realpath cache is currently using. To do so, create a new PHP file with the following contents:
<?php
var_dump(realpath_cache_size());
?>
I named mine realpath.php.
Upload it to your server and access that PHP file. You will then be shown how much memory does realpath cache use right now. For me, it’s a little over 1M:
int(1048523)
The result is given in Bytes. So in my case, 1048523 Bytes equals approximately 1.04 megabytes.
That means that I should set my realpath_cache_size to at least 1M.
note: I did test this, and for my Magento 2 installation (the VPS I tested this on had only a Magento 2 shop running) it does not go over 1M too much.
How to get to the perfect realpath_cache_size value?
Just set it to 4M. Then monitor your usage using the above ‘script’. Decrease as needed in order not to waste memory. Of course, you can go even lower if you are on a memory-starved box. (1GB RAM for example).
That is how I reached my ‘ideal’ value of 1M. To be fair 2M would probably be better but memory is kind of low in my scenario.
How to see the contents of the realpath cache?
Create another PHP file, with the following contents:
<?php
var_dump(realpath_cache_get());
?>
Mine looked like this:
array(5) {
["/var/www/html"]=> array(4)
{ ["key"]=> int(1438560323331296433) ["is_dir"]=> bool(true) ["realpath"]=> string(13) "/var/www/html" ["expires"]=> int(1574117163) }
["/var/www"]=> array(4)
{ ["key"]=> float(1.5408950988325E+19) ["is_dir"]=> bool(true) ["realpath"]=> string(8) "/var/www" ["expires"]=> int(1574117163) }
["/var"]=> array(4)
{ ["key"]=> float(1.6710127960665E+19) ["is_dir"]=> bool(true) ["realpath"]=> string(4) "/var" ["expires"]=> int(1574117163) }
["/var/www/html/printa/realpath.php"]=> array(4)
{ ["key"]=> int(4645138079431406002) ["is_dir"]=> bool(false) ["realpath"]=> string(33) "/var/www/html/mage2/realpath.php" ["expires"]=> int(1574117163) }
["/var/www/html/printa"]=> array(4)
{ ["key"]=> int(3126941982154607314) ["is_dir"]=> bool(true) ["realpath"]=> string(20) "/var/www/html/mage2" ["expires"]=> int(1574117163) }
}
What about the realpath_cache_ttl?
This sets how long an entry is stored in the cache. Because a cache hit does not extend the time to live, it does not make sense to decrease this value. On production servers, I’d set it to 300 seconds, but I guess the 120 seconds default value is good.
Conclusion
Don’t just blindly copy-paste stuff. Test, test and test some more! This way you’ll get to know how stuff works better and you’ll end up with a high performing server and you won’t waste memory.
Here are my final settings for a VPS:
realpath_cache_size = 1M
realpath_cache_ttl = 300
Hey! This does not apply only to Magento. Any PHP-based application, especially those with a huge number of files, will benefit greatly from a proper realpath_cache_size setting.