Diagnosing Zend OPcache Problems: Stale Code, Memory Exhaustion, and CLI Caching
When PHP changes don’t appear, latency spikes, or CLI jobs run slow, OPcache may be mis‑configured. This guide walks through recognizable symptoms, diagnostic checks, fixes, and escalation steps for stale code, memory limits, CLI caching, and path exclusions.
26 Sept 2026, 09:13 UTC

Recognizable Condition 1: Deployed PHP Changes Don’t Show Up on Web Requests
When a new version of a PHP file is uploaded, but the browser still serves the old output, you’re likely dealing with stale bytecode in OPcache. The cache keeps the compiled version of the script and ignores the file’s modification time if the configuration tells it to.
Cause & Diagnostic Table
| Cause | Diagnostic Signal |
|---|---|
| opcache.validate_timestamps disabled (value 0) | opcache_get_status()['scripts'][path]['mtime'] equal filemtime() |
Ordered Checks
- Run
php -i | grep opcacheon the web‑server PHP binary to confirmopcache.validate_timestamps=1.- Required permissions: read access to the PHP binary.
- Expected check: the line shows
opcache.validate_timestamps => 1 => 1.
- Use
opcache_get_status()from a test script to inspect the cached script entry:- Look for
mtimeandfile_mtimevalues. - If they match, OPcache believes the file hasn’t changed.
- Look for
- Touch the file:
touch /var/www/html/index.phpand request the page again.- Check the
mtimein the status output; it should update.
- Check the
Fixes
- Set
opcache.validate_timestamps=1in/etc/php/8.3/fpm/php.inifor the web‑server. - If you cannot change the ini, call
opcache_invalidate('/var/www/html/index.php', true)after each deployment or runopcache_reset()in a maintenance window. - For high‑frequency deployments, consider
opcache.revalidate_freq=0to check timestamps on every request.
Escalation Criteria
- If
opcache_validate_timestampsis already 1 and stale code persists, check foropcache.file_cacheenabled; a stale file in the cache directory may override the timestamp check. - Escalate to platform engineering if
opcache_reset()does not clear the stale entry within 5 minutes.
Recognizable Condition 2: Rising Request Latency and PHP‑FPM Worker Recycling
When web requests start taking longer and you notice PHP‑FPM workers being restarted, OPcache may be running out of memory. The cache fills, triggers a restart, and the new workers rebuild the cache from scratch.
Cause & Diagnostic Table
| Cause | Diagnostic Signal |
|---|---|
Ordered Checks
- Check current memory usage:
php -r "print_r(opcache_get_status()['memory_usage']);"- Look at
used_memoryandfree_memory.
- Look at
- Compare
memory_usage['used_memory']toopcache.memory_limitfromphp -i.- If used memory > 80% of limit, you’re close to exhaustion.
- Monitor
cache_fullandrestartcounters over a 5‑minute window.- Use a simple script that polls
opcache_get_status()every 10 seconds and logs the counters.
- Use a simple script that polls
Fixes
- Increase
opcache.memory_limit(e.g., from 128M to 256M) in the PHP ini. - Restart PHP‑FPM after changing the ini.
- If the application has a large number of classes, consider
opcache.max_accelerated_filesadjustments. - For long‑running scripts, enable
opcache.enable_cli=1to avoid memory churn.
Escalation Criteria
- If restarts continue after raising
memory_limitand adjustingmax_accelerated_files, investigate memory leaks in PHP extensions or custom opcode caches. - Escalate to the infrastructure team to review server memory allocation and consider adding swap or scaling the pool.
Recognizable Condition 3: CLI Scripts Run Uncached While Web Requests Are Cached
When you run a PHP script from the command line, it often executes without OPcache, resulting in slower performance for CLI jobs that could benefit from caching.
Cause & Diagnostic Table
| Cause | Diagnostic Signal |
|---|---|
Ordered Checks
- Run
php -i | grep opcache.enable_cli.- Expected output:
opcache.enable_cli => 0 => 0.
- Expected output:
- Check which ini file CLI uses:
php -i | grep "Loaded Configuration File".- Compare to the FPM ini path.
Fixes
- Edit
/etc/php/8.3/cli/php.iniand setopcache.enable_cli=1. - Alternatively, run CLI scripts with explicit ini override:
php -d opcache.enable_cli=1 long_running_job.php
Escalation Criteria
- If enabling CLI caching causes CLI scripts to crash or memory spikes, verify that the CLI environment has sufficient memory and that extensions are compatible.
Recognizable Condition 4: Specific Paths Are Never Cached Despite OPcache Being Enabled
Occasionally, developers notice that certain scripts or directories are excluded from caching, which can be due to blacklist or API restrictions.
Cause & Diagnostic Table
| Cause | Diagnostic Signal |
|---|---|
Ordered Checks
- Inspect blacklist file:
cat /etc/php/8.3/mods-available/opcache.ini | grep "blacklist"- Verify that the file path is correct and that it does not match the target script.
- Check
opcache.restrict_apiinphp -i.- If set, ensure the script is not loaded via
opcache_compile_file()oropcache_invalidate()in a restricted context.
- If set, ensure the script is not loaded via
Fixes
- Remove or adjust blacklist entries for the affected paths.
- Disable
opcache.restrict_apiif not needed, or adjust the API usage.
Escalation Criteria
- If after blacklist removal the script still isn’t cached, verify that the script’s file permissions allow PHP to read it.
- Escalate to the security team if
opcache.restrict_apiwas intentionally enabled for a reason.
Putting It All Together: A Quick Diagnostic Flow
- Confirm OPcache is enabled:
php -i | grep opcache.enabled. - Check the timestamp validation setting.
- Run
opcache_get_status()and look atcache_fullandrestartcounters. - If CLI scripts are slow, enable
opcache.enable_cli. - Review blacklist and restrict API settings for path‑specific issues.
- Apply the relevant fix and restart PHP‑FPM or the CLI process.
- Re‑run the status check to confirm counters have reset and latency has dropped.
Following this structured approach ensures you isolate the OPcache configuration that’s causing the symptom, apply the correct fix, and know when to involve platform or security teams.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.