Ahead-of-Time vs Just-in-Time Compilation
debt(d7/e3/b3/t6)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints list Blackfire and opcache-gui as tools, but these are profilers that require active investigation — there's no automated lint or static analysis that flags 'you enabled JIT but your workload is I/O-bound.' You'd only discover the misconfiguration through careful runtime profiling or benchmarking, noticing no improvement or slight overhead. Not quite d9 since profiling tools do exist and can surface the issue.
Closest to 'simple parameterised fix' (e3). The quick_fix is essentially a configuration change — toggling opcache.jit settings in php.ini or understanding when to enable/disable it. However, it's not a pure one-line fix (e1) because you first need to profile to determine if your workload is CPU-bound, and you may need to adjust JIT settings across deployment configs. Still localized to configuration, not a code refactor.
Closest to 'localised tax' (b3). The AOT vs JIT choice in PHP is primarily an infrastructure/configuration decision. It applies to web and CLI contexts but doesn't fundamentally shape application code — your PHP code stays the same regardless of JIT being on or off. The burden is localized to ops/deployment configuration and performance tuning decisions rather than imposing ongoing structural weight on the codebase.
Closest to 'notable trap' (t5), +1 to t6. The misconception field explicitly states the trap: 'PHP 8's JIT always makes PHP faster.' This contradicts the intuitive expectation that a JIT compiler = faster code. A competent developer familiar with JIT from JVM or V8 would reasonably expect universal speedups, but PHP's JIT specifically benefits only CPU-bound workloads while typical web apps are I/O-bound. The warmup penalty and potential JIT bugs add further surprise. This goes slightly beyond a standard documented gotcha because the 'obvious' assumption (JIT = faster) is wrong for the majority use case (web requests).
Also Known As
TL;DR
Explanation
AOT (Ahead-of-Time): the entire program is compiled to machine code before running. Advantages: fast startup, predictable performance, no runtime compilation overhead. Languages: C, C++, Go, Rust. Disadvantage: cannot optimise based on runtime data. JIT (Just-in-Time): compiles frequently executed code paths to machine code while running. Advantages: can use runtime profiling to optimise hot paths, supports dynamic languages. Disadvantages: warm-up time (startup slower), runtime overhead for compilation. PHP 8's JIT uses Opcache as the foundation — compiles hot opcodes to native code. Impact on PHP: significant for CPU-bound code (image processing, cryptography), negligible for typical I/O-bound web requests.
Common Misconception
Why It Matters
Common Mistakes
- Enabling PHP JIT expecting speedup for I/O-bound web apps — measure first.
- Not understanding JIT warmup — first requests are slower while code is being profiled and compiled.
- Comparing PHP JIT to Go/Rust AOT — AOT languages have no warmup and generally faster peak performance.
- Not testing JIT stability — JIT is complex; some code paths may have JIT bugs.
Avoid When
- Do not enable PHP JIT for typical CRUD web apps — the warm-up cost and memory overhead outweigh gains for I/O-bound code.
- Avoid JIT in short-lived PHP scripts (CLI one-shots) where the compilation cost exceeds total runtime.
- Do not assume JIT improves all code paths equally — profile first; unoptimised JIT can regress some patterns.
When To Use
- Prefer AOT (Go, Rust, C) for CLI tools, containers, and serverless where cold-start time and binary portability matter.
- Use JIT (PHP 8+ opcache.jit, JVM) for long-running CPU-bound workloads where runtime profiling improves hot-path throughput.
- Enable PHP JIT specifically for number-crunching, image processing, or ML inference — not for typical I/O-bound web requests.
Code Examples
; Enabling JIT everywhere without measuring:
; php.ini:
opcache.jit_buffer_size = 100M
opcache.jit = tracing
; Benchmark result: 0% improvement for DB-heavy Laravel app
; JIT overhead: 50MB memory, slower startup
; Wrong tool for the problem
; First: profile to confirm CPU-bound bottleneck
; $ php -d xdebug.mode=profile script.php
; Result: 80% time in image resize — CPU bound!
; Now enable JIT for targeted benefit:
opcache.jit_buffer_size = 64M
opcache.jit = tracing ; Best for loops
; Benchmark: 40% faster image processing
; Web endpoints: 2% faster (within noise)
; Worth it for image service, not general app