DEV Community

Magevanta
Magevanta

Posted on Originally published at magevanta.com

Magento 2 PHP 8.4 Upgrade: Real Performance Gains & a Safe Migration Checklist

Every Magento performance audit I do ends the same way: we spend weeks optimizing a custom module, fiddling with Varnish TTLs, shaving off a few milliseconds of TTFB — and the single biggest, cheapest win is still sitting untouched in php -v. Most stores run PHP 8.1 or 8.2 not because they need to, but because nobody scheduled the upgrade. Meanwhile each PHP minor release ships a few percent of free performance, better opcache behavior and lower memory usage.

This guide covers what PHP 8.4 actually gives a Magento 2 store, which Magento versions support it, and a pragmatic checklist to upgrade without burning a weekend fighting deprecation warnings.

What PHP 8.4 delivers (the honest version)

Before the features, the number that matters: measured on CMS-style workloads (which is what Magento is — object-heavy, I/O-bound PHP), PHP 8.4 is roughly 5–10% faster than 8.3, which itself was ~10% faster than 8.2, which was ~10–20% faster than 8.1 depending on the workload. Stacked up: 8.1 → 8.4 is often a 25–35% throughput improvement on the same hardware. No Redis tuning, no query optimization, no code changes — just a runtime swap.

Where does that come from?

  • Opcache improvements — better JIT tuning, faster hash tables, more aggressive opcode optimizations.
  • Reduced memory usage — PHP 8.4 continues the trend of lower per-request allocation, which matters more than raw CPU for Magento: FPM workers that use less memory per request can each serve more concurrent requests before pm.max_children becomes the wall.
  • Faster autoloading and startup — a meaningful slice of every Magento request is class loading and bootstrapping; the runtime-level gains compound with opcache preloading.
  • Incremental garbage collector (since 8.3, still relevant) — cycle collection no longer pauses the whole request, which smooths out latency spikes on long-running cron jobs and imports.

The honest caveat: don't expect a 30% TTFB drop on a cached page. If the page is served from Varnish or full-page cache, PHP barely runs. The gains show up on uncached pages, checkout (which is deliberately non-cacheable), admin operations, complex API calls, reindexing, imports and concurrent traffic. For a store with a warm cache, the win is capacity, not latency: the same server handles more checkout load during a flash sale. That's often worth more than a faster homepage.

JIT: why Magento mostly ignores it

PHP 8.0 introduced JIT, and every blog post since has asked whether Magento should enable it. Short answer: no, and 8.4 doesn't change that. JIT shines on CPU-bound pure-computation loops. Magento's request lifecycle is dominated by I/O (MySQL, Redis, filesystem, network) and object instantiation — precisely the workload where JIT overhead (memory for compiled traces, more complex opcache state) can even make things marginally slower.

The exception: if you run heavy CPU-bound PHP workloads — big product imports with lots of arithmetic, custom report generation, complex rule matching — you can A/B test opcache.jit=tracing in a staging environment and measure with a stopwatch rather than vibes. Default (off in FPM, and not enabled by Magento's config) remains the right production choice for the vast majority of stores.

What helps instead:

; php.ini — the boring wins that actually matter for Magento
opcache.enable=1
opcache.memory_consumption=512
opcache.validate_timestamps=0        ; in production only!
opcache.revalidate_freq=0
opcache.interned_strings_buffer=32   ; PHP 8.4 handles interned strings more efficiently
realpath_cache_size=4096K            ; filesystem-heavy Magento boot loves this
realpath_cache_ttl=600
Enter fullscreen mode Exit fullscreen mode

Which Magento supports PHP 8.4

Compatibility matrix, as of writing:

  • Magento 2.4.7 and earlier: PHP 8.2 max. Do not force 8.4 on these — core code (and most extensions) will throw deprecations and fatals in places.
  • Magento Open Source / Adobe Commerce 2.4.8 (April 2025): first release with official PHP 8.4 support (also the release that moved to MariaDB 11.4 and OpenSearch 2.x defaults). EOL April 2028.
  • 2.4.8-p1 and later patch releases: PHP 8.4 remains supported.

So the upgrade path is really: get to 2.4.8+, then move PHP. If you're still on 2.4.6-p5 or earlier, the PHP upgrade is a side effect of the Magento upgrade, and you should treat both as one project with a proper staging phase.

The upgrade checklist

1. Know what you're running

Before touching anything, inventory the runtime surface: PHP version on each node, FPM pool config, which web server talks to FPM, and the PHP binary used by bin/magento cron. Stores with multiple servers frequently differ between CLI and FPM — that's a silent source of "it works on my machine" disasters.

2. Fix composer constraints

The platform requirements live in composer.json and the lock file:

"config": {
    "platform": {
        "php": "8.4.0"
    }
}
Enter fullscreen mode Exit fullscreen mode

Set the platform to the target PHP version, run composer update --lock, and let Composer tell you which packages block the move. The blockers are usually old community extensions pinned to ~8.1.0 — each one needs an upgrade or a fork before you can proceed. Get this list before touching the server; it's your project plan.

3. Deprecation sweep with static analysis

PHP 8.4 added new deprecations that bite Magento custom code specifically:

  • Implicit nullable parameters (Type $x = null without ?Type) — a huge one for older modules; it's deprecated in 8.4 and will be a fatal in PHP 9. Core has been cleaned up since 2.4.8, but your custom code and old third-party modules are the risk.
  • E_STRICT and other soft removals — run a PHPStan/Pint pass at level 8+ and grep for @deprecated usage in your vendor diff.
  • Curl, OpenSSL and sodium changes — any module doing raw HTTP or crypto calls needs re-validation on 8.4.
  • Property hooks and asymmetric visibility are new 8.4 syntax; if a third-party module uses them and your deployment runs on an older PHP for CLI cron, it'll fatal. Keep all PHP runtimes in the stack on the same major.minor.

Run the full test suite + a smoke list (frontend uncached page, admin login, checkout, search, cron, queue consumers, at least one import) on staging with error_reporting(E_ALL) so deprecations surface loudly instead of silently rotting in logs.

4. Don't forget the extensions

PHP 8.4 needs current builds of bcmath, intl, gd, imagick, xsl, zip, sodium, opcache, redis, and (if you use it) ioncube — ionCube in particular lags new PHP releases, and 8.4 support required specific loader versions. Check php -m against your current environment and diff the lists; a missing extension fails silently in Magento (empty pages, broken image resize) rather than loudly.

On Debian/Ubuntu:

apt install php8.4-fpm php8.4-cli php8.4-mysql php8.4-bcmath \
  php8.4-intl php8.4-gd php8.4-xsl php8.4-zip php8.4-sodium \
  php8.4-opcache php8.4-redis php8.4-curl
Enter fullscreen mode Exit fullscreen mode

5. Measure before, measure after

The whole point is measurable gains, so capture a baseline first:

  1. Synthetic: benchmark an uncached PDP with ab/wrk (e.g. wrk -t4 -c64 -d60s against a URL with FPC and Varnish bypassed) — record requests/sec and p95 latency before and after.
  2. Real-world: run the same Blackfire or New Relic transaction profiles on the old and new runtime — compare per-transaction wall time and memory.
  3. Capacity: re-run the same concurrency test that used to push FPM to pm.max_children; the new ceiling is your flash-sale headroom.

Typical honest result after 8.1 → 8.4 with opcache tuned: p95 on uncached pages down 15–25%, memory per FPM worker down 10–20%, and the same hardware handling 20–30% more concurrent uncached requests. If you see none of that, check that FPM actually reloaded the new version (php-fpm8.4 -v + INFO: reloading in the log) — "we upgraded PHP" is a surprisingly common false claim, with old FPM sockets still serving traffic.

6. Rollback plan

Keep the old runtime installable (don't purge php8.2 packages), snapshot the FPM pool config, and make the switch a config-level toggle rather than an image rebuild: one server first, watch error logs for 24h, then the rest. A PHP upgrade gone wrong is a configuration revert, not a data migration — it should never take longer than five minutes to undo.

The bottom line

PHP 8.4 isn't a magic switch, but it's the closest thing Magento performance work has to a free lunch: 2.4.8 + PHP 8.4 + tuned opcache is a measurably faster, more memory-efficient stack with zero architectural risk, and it retires a pile of old deprecations before PHP 9 makes them fatal. The upgrade is boring, mostly compatibility work — and that's exactly why you should do it before the next flash-sale season rather than during it.

If you want to know whether your specific store (and its extension list) is actually 8.4-ready, run the composer platform check and the deprecation sweep first — those two commands answer 90% of the question in an afternoon.

Top comments (0)