Latest posts Visit blog

Released in November 2025, PHP 8.5 has one consequence above all for shop operators: the OPcache bytecode cache is now built into the PHP binary and always loaded (PHP project). This shifts the real work from the question of whether you use OPcache to the question of how you tune it and the JIT compiler to the load profiles of your online shop. This guide shows which OPcache settings save response time in practice, when JIT tracing helps on compute-heavy routes and does little on database-heavy ones - and how to anchor all of this cleanly in the professional hosting of a Shopware shop.

What Changes for Shop Servers with PHP 8.5

PHP remains the foundation of web commerce: around 69.9 percent of all websites with a known server-side language run on PHP (W3Techs), and 63.9 percent of PHP installations now run on version 8 (W3Techs). For shop systems such as Shopware, which build on the Symfony framework, an up-to-date PHP branch is therefore not optional but an operational basis. PHP 8.5 was released on 20 November 2025 (PHP.net) and continues the line of recent versions: more speed from the core, without you having to rewrite your application code.

The most important change for operations concerns OPcache. Until now the bytecode cache was an optional extension loaded via zend_extension=opcache. In PHP 8.5, OPcache is compiled into the binary and always present - the separate load line is obsolete and should be removed from old configurations (PHP project). In practice this means: the cache is there, but its default values are conservative. This is exactly where the leverage lies, because the defaults are meant for small scripts, not for a full-grown shop with tens of thousands of class files.

OPcache Is Now Built In

In PHP 8.5 the OPcache bytecode cache is no longer optional but part of the core (PHP project). Anyone migrating from PHP 8.4 should remove the zend_extension=opcache line from the configuration, because the extension is loaded anyway. However, the mere presence of OPcache does not yet mean an optimal configuration - the actual acceleration only emerges from properly set memory and validation values.

Understanding OPcache: Why the Bytecode Cache Carries Your Shop

OPcache addresses a structural peculiarity of PHP. Without a cache, on every single request the interpreter re-reads each required PHP file from disk, tokenizes it and translates it into opcodes - the intermediate language the PHP engine actually executes. In a Shopware shop with many thousands of class files, this step recurs on every page view. OPcache stores the fully compiled opcodes in shared memory. From the second call onward, the expensive parsing and compiling is skipped entirely and the engine jumps straight to execution.

The effect is considerable precisely in framework-heavy shops, because a very large number of files are included per request. When the compiled bytecode is kept in memory permanently, response times drop noticeably. For an online shop this is doubly valuable: faster response times not only improve the user experience at checkout but also feed into Core Web Vitals and thus into visibility in search. A well-configured OPcache is therefore one of the cheapest performance measures of all - it essentially costs memory and a few configuration lines.

Configuring OPcache Correctly: The Decisive Settings

The most important value is opcache.memory_consumption. It determines how much shared memory is available for the bytecode. The default is 128 MB (PHP.net) - enough for a small blog, but often too tight for a shop with extensive framework code. When the cache fills up, OPcache starts evicting entries, the hit rate drops and the advantage shrinks. For shop servers a range of 256 to 512 MB has proven effective in practice (project experience). An overly generous value does no immediate harm; it merely occupies memory that could be missing elsewhere.

opcache.ini
; Recommended baseline for a shop server
opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=1000000
opcache.validate_timestamps=0
opcache.save_comments=1

The second big setting is opcache.validate_timestamps. When active, PHP checks on every request, for every file and via a filesystem call, whether the source has changed. That is handy in development but unnecessary overhead in production. Setting the value to 0 eliminates this stat call per file and request entirely - in exchange, the cache must be reset manually after every deployment (PHP.net). How much time that saves depends on how many files a request includes and belongs measured on your own shop.

validate_timestamps=0 Needs a Deploy Step

When OPcache no longer checks timestamps, PHP does not notice code changes on its own. After every deployment the cache must therefore be actively cleared - via a restart of PHP-FPM or a call to opcache_reset() (PHP.net). Anyone who forgets this step wonders why new changes do not take effect. In a clean deployment pipeline, resetting the cache is a fixed, automated part of the process.

SettingDefaultShop productionEffect
opcache.memory_consumption128 MB256-512 MBMore classes in cache
opcache.max_accelerated_files10,000up to 1,000,000All files are cached
opcache.interned_strings_buffer8 MB32-64 MBFewer duplicate strings
opcache.validate_timestamps1 (on)0 (off)No stat call per request

Two further values round off the configuration. opcache.max_accelerated_files caps how many files may reside in the cache; the default is 10,000 and the maximum 1,000,000 (PHP.net) - large shops need a high value so that truly every class is cached. opcache.interned_strings_buffer determines how much memory is reserved for internally pooled strings; the default is 8 MB (PHP.net), and in framework-heavy applications 32 to 64 MB is common, because identical strings are held only once. What matters is to watch the actual hit rate after the change: it should stay consistently high, otherwise the memory is sized too tightly.

JIT: When Tracing Helps and When It Slows You Down

The JIT compiler (Just-in-Time) goes one step further than OPcache. While OPcache caches compiled opcodes, JIT translates frequently traversed code paths into native machine code at runtime, which the CPU executes without the detour through the PHP engine. The recommended tracing mode is enabled via opcache.jit=tracing, which internally corresponds to the numeric value 1254 (PHP.net). That sounds like a pure win - but it only is for certain load profiles.

The benefit of JIT depends decisively on where your shop spends its time. For CPU-bound code - such as image processing, PDF generation, elaborate pricing or discount calculations, or large data imports - JIT can speed things up noticeably. For typical web applications, which spend most of their time on database queries, network access and waiting for external services, the gain is small by contrast. That is not a weakness of JIT but plain arithmetic: if a route waits 60 percent of the time on input and output, even doubling the remaining 40 percent CPU share ultimately yields only around 20 percent.

jit.ini
; Enable JIT only when routes are truly CPU-bound
opcache.jit=tracing
opcache.jit_buffer_size=128M
Measure First, Then Enable

JIT is not a switch you flip blindly. The gain depends so strongly on the concrete load profile that only a before-and-after measurement of real response times provides clarity - synthetic benchmarks easily mislead here. Experience shows JIT rarely pays off in the classic shop checkout, while compute-heavy background processes such as import, image scaling or report generation can benefit noticeably. Separating the two extracts the maximum without risking the latency of customer-facing routes.

JIT Tracing Helps

Compute-heavy tasks without waiting: pricing and import logic, image processing as well as PDF and report generation. Noticeable jumps are realistic here.

JIT Adds Little

Database- and I/O-bound routes such as product lists or the checkout in the B2B shop: the bottleneck is the wait, not the CPU - the uplift usually stays small.

Preloading and Further Levers Beyond OPcache

Beyond OPcache and JIT there are further settings. Preloading loads selected classes into memory at the start of the PHP process, so they are immediately available across all requests. The Symfony project cites an improvement of 30 to 50 percent for real applications (Symfony). What matters is the starting point: for applications that are already fast, preloading weighs heavily, while for sluggish pages the gain disappears in the noise. Only a before-and-after measurement shows what it delivers in your own shop.

Two further points are worth a look. The realpath_cache stores resolved file paths and relieves the filesystem when there are many includes - higher values make sense for large shops. And the PHP-FPM process manager helps decide how many parallel requests a server can handle: too few workers slow things down under load, too many exhaust the memory. These sizes should be dimensioned to fit the shop's load profile, ideally based on real measurements rather than blanket rules of thumb. Anyone realigning their infrastructure anyway should also factor in the question of data sovereignty and server location.

Migrating from PHP 8.4 to 8.5: The Safe Path

The jump from PHP 8.4 to 8.5 is uncritical for most shops but wants to be prepared. We have described the full procedure for Shopware in a dedicated guide on the PHP 8.5 migration from an agency view; here the focus is on the tuning-relevant steps. It is important to check the PHP compatibility of the shop version in use: Shopware, for example, introduced official support for PHP 8.5 with a version from February 2026 (Shopware). Anyone on an older release sensibly updates the shop first and PHP second.

  1. Check compatibility: verify the shop version, plugins and custom extensions for PHP 8.5 clearance before anything is switched in production.
  2. Test in staging: raise an exact copy of the shop to PHP 8.5 and fully run through all critical processes - checkout, payment, import.
  3. Work through deprecations: fix the notices reported in the log so they do not turn into real errors in a later version.
  4. Configure OPcache and JIT: set the values described above and - importantly - add the cache reset to the deployment routine.
  5. Measure and go live: compare response times before and after the switch, then go into production in a controlled way and keep an eye on the hit rate.
Migration Is a Good Occasion for Fine-Tuning

A PHP migration touches the entire runtime environment anyway. That is the ideal moment to review OPcache and JIT values, PHP-FPM sizing and the deployment process together. In consulting we set a realistic target per shop for this, rather than adopting default values unchecked - because the fitting configuration is, from experience, always the one that matches the actual load profile.

Anchoring PHP Performance in Hosting for Good

Speed in e-commerce is not a one-off project but an operational trait. OPcache and JIT only unfold their value when they fit the load profile, are cleanly reset after every deploy and have their hit rate monitored. In XICTRON's managed hosting we set up PHP 8.5 so these points are not left to chance but are a fixed part of operations.

OPcache Sized to Fit

Memory, file limit and validation tuned to your shop - with a monitored hit rate instead of conservative default values.

JIT by Load Profile

Tracing where compute-heavy processes run, and deliberately off where I/O sets the pace.

Safe Deploy with Cache Reset

validate_timestamps=0 only with an automated OPcache reset in the deployment pipeline.

Measured, Not Guessed

Response times before and after every change - including for data-intensive ERP price lists in the B2B shop.

Whether a fresh installation or a migration from PHP 8.4: what matters is that OPcache and JIT are configured according to the real load profiles of your shop, not by rule of thumb. We review the current state of your PHP configuration, migrate to PHP 8.5 in a controlled way and back every change with a before-and-after comparison. Talk to our team to put your shop's speed on a solid, measurable foundation.

Sources and Studies

This article draws on the official PHP.net documentation on OPcache and JIT, the release details for PHP 8.5, the UPGRADING notes of the PHP project on the built-in OPcache extension, the preloading figures from Symfony, as well as the usage data from W3Techs and the version notes from Shopware. The figures cited are guidance values and can vary depending on application, hardware and point in time; this article does not replace individual performance or security advice. Status: September 2026.

OPcache is compiled into the binary in PHP 8.5 and always available (PHP project). The old zend_extension=opcache line is therefore obsolete and should be removed from the configuration. The cache is then active, but with conservative default values - the actual acceleration only emerges from adjusted memory and validation settings.

With opcache.validate_timestamps=0, a filesystem call for change checking is eliminated per file and request. How much time that saves depends on how many files a request includes and can only be measured on your own shop. The price for it: after every deployment the cache must be actively cleared (PHP.net), otherwise code changes do not take effect.

That depends on the load profile. For compute-heavy tasks such as image processing or import logic, JIT in tracing mode can speed things up noticeably. For database- and I/O-bound web routes, by contrast, the gain usually stays small. So the rule is: first measure the real response times, then decide selectively rather than enabling it across the board.

The default of 128 MB (PHP.net) is usually too tight for larger shops. A range of 256 to 512 MB has proven effective (project experience), combined with a high value for max_accelerated_files up to 1,000,000 (PHP.net) so that truly every class file is cached. The hit rate should stay consistently high after the change; if it drops, the memory is sized too tightly.

OPcache stores compiled bytecode in memory so that files are not re-parsed on every request. JIT goes further and translates frequent code paths into native machine code at runtime. OPcache helps virtually every shop, JIT mainly CPU-bound tasks. For most web applications a well-configured OPcache is the bigger lever.

We check the shop version, plugins and extensions for PHP 8.5 clearance, migrate in a staging environment first and work through reported deprecations. We then configure OPcache and JIT to fit the load profile, anchor the OPcache reset in the deployment pipeline and back every change with a before-and-after comparison of response times. This way PHP performance typically becomes a fixed, measurable part of hosting (project experience).