PHP-FPM Opcache optimal settings? opcache.enable_cli and opcache.file_cache

duntuk

Verified User
Joined
Jan 23, 2007
Messages
56
Been researching the following settings, but still not sure what are the best settings here for PHP-FPM (and multiple PHP-FPM version):

opcache.enable_cli
opcache.file_cache

Ref:

Currently my settings are, and using multiple PHP-FPM versions 7.2, 7.3, 7.4:

opcache.enable_cli = 0
opcache.file_cache = NULL


opcache.enable_cli : CURRENT documentation says "Enables the opcode cache for the CLI version of PHP" (which is command line PHP). However many sites say to leave this off.

opcache.file_cache : Been out since PHP 7.0; can't really see any recommendations for this setting. (This looks like a good feature to enable, as it acts as a fail-safe in case you exhaust your memory storage; and is suppose to make re-caching faster... But again, don't see much on this...)
 
The websites do not use the CLI version of PHP. That's why it's OFF and usually should be OFF.

Regarding the file_cache -it's a second level cache: it is used to prewarm the main one on restarts. Unless you restart your server very frequently for some reason AND it is a heavy loaded one, this should not be used. Also if you use it, make sure that the file is placed outside of your main HDD array - you don't want your main disk drive to be loaded with operations which are not needed for serving the clients.

P.S. For me on shared hosting the opcache is just a RAM waster. But it really depends on every specific case and server.
 
I suppose it depends on how you have PHP set up. But in a php-fpm environment on a shared (multi-tenant) hosting server, I would think file based opcache would have merits.

If you're using memory based opcache there exists the potential that different users would be able to view the cache from other users. This would seem to create potential privacy concerns.

But with file based opcache - if each user's php-fpm pool has a defined opcache.file_cache directory specific to their user's read/write access - then this would prevent other users from being able to read that cache. Wouldn't it?
 
@sparek, it should be perfectly safe to use memory based opcache if you have set the correct settings, for example:

Code:
opcache.validate_permission=1
"Validates the cached file permissions against the current user": https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.validate-permission

Code:
opcache.validate_root=1
"Prevents name collisions in chroot'ed environments. This should be enabled in all chroot'ed environments to prevent access to files outside the chroot": https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.validate-root

Code:
opcache.use_cwd=1
"If enabled, OPcache appends the current working directory to the script key, thereby eliminating possible collisions between files with the same base name. Disabling this directive improves performance, but may break existing applications": https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.use-cwd

@wattie, We use php-fpm and opcache on all our shared hosting servers, and my experience is that it give better performance, to me it is not a ram waster.

On average we cache about 400000 php script in opcache on each server, wich uses about 15 GB ram. In addition we have a custom setup with file based opcache on ssd disk as a second level fallback cache, those files is stored in each users home directories at /home/user/.opcache - the big benefit of this, is that each time opcache is emptied because of a reload of apache or php-fpm, then the first visit to a php script will get the file based opcache script, and then the second request will get it from ram.
 
Last edited:
But can't a user use the opcache_get_status() function to see a list of all of the files - including those from other users - that exist within the cache?

I don't know if there's anything they can actually do with those files - but they know they exist.

I suppose you could disable the opcache_get_status() function in PHP.

I'm not really meaning to advocate for one way or another. Just healthy discussion.
 
@sparek, I tested by using this script on a regular user domain/website: https://github.com/rlerdorf/opcache-status/blob/master/opcache.php

The script does not show any file paths or file names from the cache when clicking the tab "Scripts (378821)". This confirms that it is not possible for regular users to see any paths or file names from the cache. All they can see is the general statistics wich would also be available in a PHP info page.

So the answer to your assumption and question is: No, a user can't use the opcache_get_status() function to see a list of all of the files, at least not if you use the settings I posted in previous reply.

You do not need to disable the opcache_get_status() function in PHP.
 
Last edited:
But with file based opcache - if each user's php-fpm pool has a defined opcache.file_cache directory specific to their user's read/write access - then this would prevent other users from being able to read that cache. Wouldn't it?

File cache does not replace the memory cache - it duplicates it. The file cache is used only when the memory cache for some reason get flushed.

As ditto said, opcache have settings which prevent users from interacting with each other.
 
Well... I'm really not able to duplicate this.

But admittedly, I'm using a slightly modified and custom php-fpm deployment system. And unfortunately I'm a bit busy with other projects and really don't have time to dive into this right now.

From what I'm seeing, even with opcache.validate_permission, opcache.validate_root, opcache.use_cwd enabled, I'm still able to see the full path of other user's cached PHP scripts with both opcache_get_status() and the opcache-status script that was previously linked to. If I add opcache_get_status() to the disabled function list, then that stops it - and that is and was my previous solution to all of this.

But according to this discussion I still have something amiss compared to others. I may have to revisit this later when I can dedicate time to looking at this. But for now I'm willing to let it die.
 
Back
Top