OPcache Internals — How Bytecode Caching Works
Also Known As
OPcache
opcode cache
opcache.so
PHP bytecode cache
TL;DR
OPcache compiles PHP source files to bytecode once and stores the result in shared memory — subsequent requests skip parsing and compilation entirely, making PHP 5–10x faster for I/O-bound workloads.
Explanation
Without OPcache, every PHP request parses source files into an abstract syntax tree, compiles the AST to opcodes, and then executes those opcodes. OPcache intercepts the compile step and stores the resulting opcode array in a shared memory segment accessible to all PHP-FPM worker processes. On subsequent requests, OPcache finds the cached opcodes by filename hash, validates they are still current (via file mtime or inode checks), and passes them directly to the Zend VM — skipping parsing and compilation entirely. PHP 7.4 added preloading: specific files can be compiled at FPM startup and permanently kept in the shared segment, eliminating even the cache lookup for those files.
Common Misconception
✗ OPcache caches the output of PHP scripts (HTML, JSON). It caches compiled bytecode — the intermediate representation of PHP source code. Output caching requires a separate mechanism like Redis or a reverse proxy cache.
Why It Matters
OPcache is the single highest-ROI PHP optimisation available — it is free, built-in since PHP 5.5, and typically reduces request processing time by 30–80% for framework applications. Not enabling it in production is one of the most common PHP performance mistakes.
Common Mistakes
- Leaving opcache.validate_timestamps=1 in production — this checks file modification times on every request, partially defeating the purpose of caching.
- Setting opcache.memory_consumption too low — when the shared memory fills up, OPcache silently stops caching new files; check opcache_get_status()['memory_usage'] regularly.
- Forgetting to restart PHP-FPM after deploys when validate_timestamps=0 — workers continue serving old bytecode until restarted.
- Not setting opcache.max_accelerated_files high enough — Composer projects with vendor dependencies often have 10,000+ PHP files; the default of 10,000 may be insufficient.
Code Examples
✗ Vulnerable
; ❌ php.ini — OPcache disabled or poorly configured for production
; opcache.enable=1 ; commented out — OPcache inactive
opcache.memory_consumption=64 ; too small for a framework app
opcache.validate_timestamps=1 ; fine in dev, wasteful in production
opcache.revalidate_freq=2 ; checks file mtimes every 2 seconds
opcache.max_accelerated_files=2000 ; too low for Composer projects with 10k+ files
✓ Fixed
; ✅ php.ini — production OPcache settings
extension=opcache
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256 ; 256MB for large frameworks
opcache.interned_strings_buffer=16 ; Saves memory for repeated strings
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; Disable in production — restart FPM on deploy
opcache.save_comments=1 ; Required for Doctrine/annotations
opcache.preload=/var/www/preload.php ; PHP 7.4+ preloading
opcache.preload_user=www-data
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
23 Mar 2026
Views
22
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
Amazonbot 1
No pings yesterday
Amazonbot 9
Perplexity 2
Google 2
ChatGPT 1
Ahrefs 1
Also referenced
How they use it
crawler 14
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Verify OPcache is active: php -r 'var_dump(function_exists("opcache_get_status"));' — if false, add 'extension=opcache' and 'opcache.enable=1' to php.ini. In production set 'opcache.validate_timestamps=0' and 'opcache.memory_consumption=256'.
📦 Applies To
PHP 5.5+
web