OPcache settings that actually move the needle on PHP 8.2
Spent last week benchmarking OPcache configurations on a Laravel 10 app running PHP 8.2. Sharing the settings that made a real difference.
The defaults are conservative. On a prod server with enough RAM, increasing the string buffer and file count limits has a measurable impact.
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.enable_file_override=1
validate_timestamps=0 is the big one. On a server where you control deploys, turning off inode checks drops latency on hot paths noticeably.
validate_timestamps=0 is standard for production but make sure your deploy process does a cache reset. We run php artisan opcache:clear (or the equivalent php -r “opcache_reset();”) as part of the deploy script.
max_accelerated_files needs to match or exceed the number of PHP files in your project including vendor. Run find . -name "*.php" | wc -l in your project root to get the real number.
On Swoole-based setups you do not get request-level OPcache stats because the process does not restart. Use opcache_get_status() periodically to check hit rate. Anything below 90% and your memory_consumption is probably too low.
enable_file_override=1 speeds up include_once and require_once calls because they skip the realpath lookup. Recommended for any app with deep vendor trees.
What about opcache.jit? I see it recommended everywhere but on our app it did not change response time at all.
JIT helps CPU-bound code. Web apps doing mostly IO (DB queries, HTTP calls) will see close to zero benefit. JIT shines on numeric processing, image manipulation, parsing loops. For typical Laravel controllers the bottleneck is network IO, not opcode execution.
Agreed. We enabled JIT on a data transformation pipeline and saw 30% improvement there. On the API layer, nothing measurable.