Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

JIT and Performance in PHP 8

Since 8.0, the JIT compiler translates PHP into machine code. For typical websites it adds little; OPcache, current versions and clean configuration deliver more.

Last updated 5 min readPHP knowledge

In short: The PHP JIT (just-in-time compiler) translates frequently executed PHP code into machine code at runtime. It arrived with PHP 8.0, is part of OPcache and has been switched off by default since PHP 8.4. Compute-intensive tasks become noticeably faster as a result; typical websites such as WordPress hardly do. The bigger gain comes from OPcache, a current PHP version and suitably tuned process management, and every current version also brings the necessary security fixes.

What is the JIT compiler in PHP?

PHP is an interpreted language: the source code is first translated into bytecode, so-called opcodes, and the Zend Engine executes these. A JIT goes one step further. It observes which code sections run often and translates exactly these into machine code for the processor. From then on they run without the detour through the interpreter.

The RFC that introduced it describes the JIT as an almost independent part of OPcache. The generated machine code lives in an additional area of the shared OPcache memory. With PHP 8.4, the project rebuilt the JIT; according to the release page, the new implementation is based on the IR framework, a shared intermediate representation for code generation. How the engine works underneath is explained in the Zend Engine.

OPcache first: the real performance basis

Without OPcache, PHP translates every file anew on every request. OPcache keeps the bytecode in shared memory so that all workers reuse it. For a website with a content management system, this is by far the most important lever. Since PHP 8.5, according to the accepted RFC, OPcache is compiled firmly into PHP; the familiar ini settings still control whether the cache is active.

Important default values according to the manual: opcache.enable=1, opcache.enable_cli=0, opcache.validate_timestamps=1 and opcache.revalidate_freq=2. With the last setting, OPcache checks at most every two seconds whether files have changed. Anyone who switches off validate_timestamps must clear the cache or restart PHP after every deployment. More on this under OPcache explained.

Configuring the PHP JIT: modes and settings

The JIT is controlled by two directives:

Directive Default from 8.4 Default before 8.4 Meaning
opcache.jit disable tracing JIT mode
opcache.jit_buffer_size 64M 0 Memory for generated machine code, 0 switches the JIT off

For opcache.jit, the manual lists these values: disable (completely off, cannot be switched on at runtime), off (off, but can be switched on at runtime), tracing or on (recommended for most users) and function. There is also a four-digit numeric notation for fine-tuning.

; enable the JIT deliberately, e.g. for compute-intensive workers
opcache.enable=1
opcache.jit=tracing
opcache.jit_buffer_size=64M

The OPcache status shows whether the JIT is running:

php -i | grep -i "opcache.jit"          # CLI settings
php --ri "Zend OPcache"                 # configuration of the OPcache extension

Note that the command line can use different settings from PHP-FPM. For web operation, what counts is the output of phpinfo() in the FPM context, ideally retrieved internally only and removed again afterwards.

What does the JIT deliver in practice?

The RFC authors measured: the synthetic script bench.php ran more than twice as fast with the JIT. With real applications, the gain was small; WordPress reached 326 instead of 315 requests per second, and the PHP parser ran about 1.3 times as fast. The RFC states openly that the JIT does not noticeably speed up real applications such as WordPress.

The reason lies in the profile of typical web applications. They spend most of their time waiting for the database, file system or external services. A faster processor path helps little there. Image processing in PHP, mathematical calculations, parsers or long-running workers, on the other hand, can benefit.

Performance without the JIT: the more effective levers

For company websites and shops, this order is worthwhile:

  1. Current PHP version: New versions bring optimisations and above all security fixes.
  2. Size OPcache correctly: enough memory and space for all files of the application.
  3. Tune PHP-FPM appropriately: adjust pm.max_children to the available RAM instead of raising it blindly.
  4. Check the database: find slow queries, set indexes.
  5. Application-level caching: page or object cache where the system supports it.
  6. Measure instead of guess: request_slowlog_timeout in PHP-FPM writes a backtrace to the slow log for slow requests.

JIT, performance and security

Performance and security are more closely linked than they seem. First: every additional component is additional code. The RFC that introduced it itself names the risk of bugs in the JIT, in code generation and register allocation, as well as the harder debugging. Anyone who does not measurably need the JIT leaves it at the default disable.

Second: OPcache and workers hold code in memory. After a security update such as the one for PHP2Shell, old processes with old code keep running until they are restarted. Clearing the cache alone does not replace this restart, because the vulnerabilities CVE-2026-109618 and CVE-2026-109619 sit in the PHP binary itself.

Third: the best performance gain, a current version, is at the same time the most important protective measure. PHP 8.2 reaches end of support on 31 December 2026; anyone who switches to 8.4 or 8.5 now gains both. How we keep systems permanently fast and hardened is described in server hardening for PHP web servers.

How does PHP SOS help?

  • Baseline analysis: We read out OPcache, JIT and FPM settings and compare them with load and RAM.
  • Measure bottlenecks: With the slow log and server metrics, we find where the time is actually lost.
  • Configure securely: The JIT only where it demonstrably helps; OPcache so that deployments and updates take effect cleanly.
  • Plan updates: Version changes with testing and a documented restart, so that speed and patch level are right.

Frequently asked questions

Is the JIT active in PHP by default?

Not any more since PHP 8.4: the default value of opcache.jit is disable. Before that, tracing was preset, but the buffer opcache.jit_buffer_size was set to 0, so the JIT did not run either.

Does the JIT make WordPress faster?

Hardly. Even in the RFC that introduced it, the authors write that the JIT does not noticeably speed up real applications such as WordPress. Their measured value rose from 315 to 326 requests per second.

Do I need OPcache if I do not use the JIT?

Yes. OPcache stores the translated bytecode in shared memory and saves recompiling on every request. For almost every PHP website this is the most important performance lever. Since PHP 8.5, OPcache is built into PHP itself.

Is the JIT a security risk?

More code means more possible errors. The RFC that introduced it itself names the risk of bugs in the JIT and the harder debugging. If you do not need it, leave it off; if you use it, you should apply updates particularly promptly.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help