Magento 2 Performance Optimization Checklist

Magento 2 Performance Optimization Checklist

A checklist is only useful if it's in the right order. This one is ordered by impact and by dependency: infrastructure first, because it sets the ceiling for every page; frontend last, because it can never outrun a slow backend. Work top to bottom. Don't jump to the frontend section because it's the visible one — a store returning HTML in 1,800ms cannot pass LCP no matter how well you tune images.

This is the run-list. For the reasoning behind each item — why Varnish hit rate matters more than installing Varnish, why native JS bundling hurts on HTTP/2 — see the companion Magento 2 performance guide. Here we just work the list.

Before you touch anything: baseline

You can't prove a win you didn't measure. Record these numbers first, from field data, not just a lab run:

  • LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1 — the three Core Web Vitals Google actually ranks on
  • TTFB ≤ 800ms — not a Core Web Vital, but the foundation under all of them

Then:

  • Pull field data from PageSpeed Insights (CrUX) for your top three page types — home, category, product — separately for mobile and desktop.
  • Run Lighthouse for diagnosis only. Lab ≠ field. A store can score 95 in Lighthouse and still fail Core Web Vitals in the field, because real users hit uncached pages, slower networks, and logged-in states the lab run never touches.
  • Test a logged-in, uncached page too — that's the slow path a cold anonymous Lighthouse run never sees.
  • Write the numbers down with a date. CrUX is a 28-day rolling window, so you'll re-check in about a month, not the same afternoon.

Layer 1 — Backend and infrastructure (the ceiling)

The biggest and cheapest wins live here. Nothing downstream can beat the TTFB this layer produces.

Full-page cache (Varnish)

  • Varnish is in front of Magento, not the built-in PHP cache. Confirm a HIT on a cacheable page: curl -sI https://yourstore.com/ | grep -i x-magento-cache-debug.
  • The cache hit rate is healthy — aim well above 80%. Check with varnishstat -1 | grep cache_hit. We routinely audit stores running Varnish under 40%, which means most visitors get the slow path anyway.
  • UTM and marketing params aren't fragmenting the cache. Normalize or strip ?utm_* in VCL so each campaign link doesn't mint a unique cache entry.
  • Nothing flushes the whole cache on every product save. A full flush during business hours keeps the store permanently cold.

Private content (the hole-punching tax)

  • Audit every etc/frontend/sections.xml in the codebase. Each custom section adds payload to the /customer/section/load request that fires on nearly every page.
  • The section/load response is small and fast. Check it in the Network tab logged in, with a cart. We've seen 200KB+ responses taking 800ms undo an otherwise fast cached page.

Redis

  • Separate instances (or at minimum separate databases) for default cache, page cache, and sessions — so a session-heavy spike can't evict your cache entries.
  • maxmemory-policy allkeys-lru on cache instances. The default noeviction throws hard errors when Redis fills up instead of dropping old keys.
  • Redis isn't constantly evicting. Check redis-cli info stats | grep evicted_keys and redis-cli info memory.

PHP and OPcache

  • PHP 8.4 on 2.4.8 (8.4 is the recommended production branch). Upgrading from an older branch is typically a 15–25% execution-time win with no code changes. Note 2.4.9 requires PHP 8.4 or 8.5 and drops 8.2 entirely.
  • OPcache sized for Magento: opcache.memory_consumption=512 or more, opcache.max_accelerated_files=60000, and opcache.validate_timestamps=0 in production.
  • Realpath cache raised: realpath_cache_size=10M, realpath_cache_ttl=86400.
  • Composer autoloader optimized as part of deploy: composer dump-autoload -o --apcu.

MySQL

  • innodb_buffer_pool_size is adequate — a large share of the working set should fit in RAM.
  • The slow query log is on and reviewed. A single unindexed custom query can dominate TTFB on one page type while every other page looks fine.

Layer 2 — Magento configuration hygiene

Free wins. These are settings, not engineering.

  • Production mode. bin/magento deploy:mode:show returns production. Developer mode on a live store is a large, silent tax.
  • Indexers on schedule. bin/magento indexer:show-mode — everything Update by Schedule. "Update on Save" locks tables on a large catalog and drags both admin and storefront.
  • Cron is actually running. bin/magento cron:status, plus monitoring on the cron_schedule table. Broken cron means stale indexes, an unprocessed message queue, and slow-motion degradation that's hard to attribute to a cause.
  • Flat Catalog is OFF. It was deprecated years ago and now adds indexing overhead with no query benefit, since search runs through OpenSearch. It survives in stores purely because old blog posts still recommend it.
  • Native JS bundling and JS/CSS merge are OFF. On HTTP/2 and HTTP/3 the multi-megabyte bundle is a parse-and-execute tax that lands straight on your INP. Do bundling in a real build pipeline with code splitting instead.
  • Magento's built-in JS minifier is OFF — it's slow and buggy on deploy. Minify in the build step or at the CDN edge.
  • Async options enabled where they fit — asynchronous indexing, async order-email sending, and deferred stock updates for high-volume stores.
  • OpenSearch 2.19 (the 2.4.8 target). Elasticsearch support was removed in 2.4.8, so if you're upgrading from an older branch this is a migration item, not a footnote.
  • OpenSearch has enough heap and isn't the hidden bottleneck on category and layered-navigation pages with a large catalog.

Layer 4 — Frontend and assets

Only now — once the backend can deliver HTML quickly — does frontend work actually pay off.

  • The LCP image is preloaded with fetchpriority="high" and is not lazy-loaded. Lazy-loading the hero or first product image is the single most common self-inflicted LCP wound we find.
  • Every image and embed has explicit width/height (or a reserved aspect ratio). This alone fixes most CLS.
  • WebP or AVIF served with automatic format negotiation at the CDN (Cloudflare, Fastly, CloudFront). No codebase changes required.
  • Everything below the fold is lazy-loaded — including the parts most themes eagerly render.
  • Render-blocking CSS is reduced, with critical CSS inlined where the theme supports it.
  • Third-party scripts are audited. Tag managers, chat widgets, and A/B tools are frequently the biggest single INP contributor. Load them deferred, and make each one justify its cost.

The theme question, briefly

If a Luma store still fails INP and LCP after everything above, you're probably hitting Luma's structural ceiling — RequireJS and Knockout.js ship a large JavaScript graph on every page. Hyvä replaces that with Tailwind and Alpine and ships a fraction of it; migrated stores commonly go from failing two of three Core Web Vitals to passing all three before any custom tuning. But it's a paid license and a frontend rebuild, not a config flag. The honest rule: migrate if you're already redesigning or replatforming; otherwise targeted optimization buys real gains for far less. The full trade-off is in the performance guide.

Verify you actually won

  • Re-pull CrUX / PageSpeed field data about 28 days after the change. CrUX is a 28-day rolling window, so a same-day lab improvement isn't proof.
  • Compare against your dated baseline, per page type, mobile and desktop.
  • Keep watching TTFB and Varnish hit rate as ongoing signals, not a one-time check — both drift as the catalog and traffic grow.

One deadline worth flagging

If you're on Magento 2.4.6, support ends August 11, 2026 — no more security patches or bug fixes after that. At that point the upgrade is a security deadline as well as a performance opportunity, and Adobe supports going directly from 2.4.6 to 2.4.8 without the intermediate step. See the 2.4.6 to 2.4.9 upgrade guide.


Emyrix does Magento and Adobe Commerce performance optimization — profiling, caching architecture, and Core Web Vitals work, measured against field data rather than a lab score. If your store is slow and you'd rather know why than guess, get in touch.

#magento #performance #core-web-vitals #redis #opensearch

Need this done properly?

We do this work every week.

Magento upgrades, performance audits, and emergency support — scoped honestly, delivered by the engineers who do the work.