← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

OPcache Internals — How Bytecode Caching Works

PHP PHP 5.5+ Intermediate
debt(d7/e1/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7) — misconfiguration is silent; you only notice via opcache_get_status() inspection or performance monitoring. No standard linter flags missing OPcache config.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1) — quick_fix is literally adding two ini directives (extension=opcache, opcache.enable=1) plus tuning a couple of values. No code changes required.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3) — OPcache configuration lives in php.ini and affects deploy workflows (must restart PHP-FPM, manage memory limits, max_accelerated_files). It imposes ongoing operational awareness but doesn't shape application code.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (documented gotcha)' (t5) — misconception confuses bytecode caching with output caching, and the silent failure modes (memory full → stops caching, validate_timestamps=0 → stale code after deploy) are classic gotchas devs learn after being burned once.

About DEBT scoring →

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

Added 23 Mar 2026
Views 49
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W 1 ping T 0 pings F 4 pings S 0 pings S 1 ping M 1 ping T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 10 Google 6 ChatGPT 3 Ahrefs 3 SEMrush 3 Perplexity 2 NotebookLM 2 Scrapy 2 Claude 1 Meta AI 1
crawler 30 crawler_json 3
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


✓ schema.org compliant