PHP JIT — When It Helps (and When It Doesn't)
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The term's detection_hints.tools lists blackfire, phpbench, and opcache-gui — all specialist profiling/benchmarking tools. You cannot know if JIT is helping or hurting without actually profiling your application. A standard linter won't tell you whether your workload is CPU-bound or I/O-bound.
Closest to 'simple parameterised fix' (e3). The quick_fix indicates enabling JIT is a configuration change (opcache.jit=tracing, opcache.jit_buffer_size=128M) — not a one-line code change but a straightforward INI adjustment. However, the real effort is in benchmarking before/after to validate the change helps, which may touch deployment configs across environments.
Closest to 'localised tax' (b3). JIT is a runtime configuration choice that applies to PHP 8+ in web/cli contexts. It doesn't shape your application architecture or impose ongoing maintenance overhead. The choice is isolated to OPcache configuration — one component pays (ops/deployment), rest of codebase unaffected. No structural dependency introduced.
Closest to 'serious trap' (t7). The misconception field explicitly states developers believe 'Enabling JIT always speeds up PHP applications' when in reality JIT benefits CPU-bound code only, and typical web applications are I/O-bound. This contradicts how JIT works in other ecosystems (JavaScript V8 JIT helps general web code), making it a serious conceptual trap for developers coming from Node.js or expecting universal speedups.
Also Known As
TL;DR
Explanation
PHP 8.0 introduced a JIT compiler (tracing and function modes) as an opcache tier. JIT compiles frequently-executed bytecode to native machine code, eliminating Zend VM interpreter overhead. Benchmarks show 2–4x speedups for pure CPU-bound PHP (number crunching, image processing, ML inference). For typical web applications dominated by database and HTTP I/O, JIT provides little measurable improvement — the CPU is rarely the bottleneck. Enable with opcache.jit=tracing and opcache.jit_buffer_size=128M. Profile first to confirm CPU is actually the bottleneck before expecting JIT to help.
Common Misconception
Why It Matters
Common Mistakes
- Enabling JIT and expecting web application speedups — most PHP web apps are I/O bound; JIT helps CPU-bound code.
- Not enabling OPcache first — JIT requires OPcache and builds on top of it.
- Using JIT mode 1255 without benchmarking — different modes (tracing vs function) suit different workloads.
- Not setting opcache.jit_buffer_size — JIT silently does nothing without a buffer allocated.
Code Examples
; php.ini — JIT not configured:
opcache.enable=1
; opcache.jit=1255 ; Missing — JIT disabled
; opcache.jit_buffer_size= ; Missing — required
; Correct for CPU-bound workloads:
opcache.jit=1255
opcache.jit_buffer_size=128M
; php.ini — enable JIT (PHP 8.0+)
; JIT only helps CPU-bound code — not typical web I/O workloads
opcache.enable=1
opcache.jit_buffer_size=128M
opcache.jit=tracing ; best for most workloads
; options: disable=0, minimal=1205, function=1205, tracing=1254
; Verify JIT is active:
; php -r 'var_dump(opcache_get_status()["jit"]);'
; Good for: image processing, data transformation, scientific computing
; Neutral for: typical Laravel/Symfony request-response (I/O bound)
; Benchmark your specific workload before relying on JIT gains