Chat on WhatsApp

Why is Magento slow? The real root causes

Magento is slow when one of four tiers misbehaves: the server stack, the extension graph, the frontend renderer, or the indexer and caching layer. Here is the honest breakdown and the fix order I use on every audit.

Why is Magento slow? The honest answer

Why is Magento slow? Magento is slow because it is the most flexible e-commerce framework on the market, and that flexibility has a cost: every request walks through hundreds of dependency-injection nodes, a plugin (interceptor) graph generated at compile time, an indexer pipeline that spans nine tables, a Knockout.js shopping-cart sidebar, and a RequireJS module loader that asynchronously fetches 150–200 small JavaScript bundles before the page is fully interactive. None of those mechanisms are inherently bad. They are how Magento delivers the customisation surface that Shopify Plus cannot. But each layer is a place where a misconfiguration, a sloppy third-party extension, or a missing cache turns into latency.

The honest framing: a well-tuned Magento 2.4.9 store on Hyvä, with PHP 8.3, Redis/Valkey for sessions and cache, OpenSearch 2.x, Varnish 7.x or FPC, and a clean extension audit, will hit 90+ Lighthouse on mobile and sub-200ms TTFB on cached pages. A neglected store on PHP 7.4, the file cache backend, sixteen unmaintained extensions and Luma will sit at 30 Lighthouse mobile and 2s TTFB. The difference is not Magento — it is whether anyone has done the audit.

I run this audit weekly. The bottleneck is almost always in one of four tiers. I will walk through them in the order I check, because fixing them out of order wastes hours. Server tier first, because everything downstream assumes it works. Indexer and cache second, because misindexed state masks every other symptom. Extensions third, because a single bad interceptor can hide a clean server config. Frontend last, because that is where Hyvä — or the lack of it — dominates the mobile experience.

Server-tier bottlenecks: PHP-FPM, MySQL, Redis, OpenSearch

The server tier is where I start every audit, because a misconfigured PHP-FPM pool will make every other tier look broken. Magento 2.4.9 expects PHP 8.1 — 8.4, OPcache enabled with a preload file, JIT off (the gains are marginal and the stability cost is real on long-running processes), and PHP-FPM in dynamic mode with pm.max_children sized to your peak concurrent request rate. On a 16GB VPS with 80MB peak PHP memory per worker, that is around 80–100 children. Anything lower and you queue under load, anything higher and you swap.

MySQL is the next checkpoint. Magento 2.4.9 needs MySQL 8.0 (or MariaDB 10.6+), innodb_buffer_pool_size sized to 60–70% of available RAM on a dedicated DB host, innodb_flush_log_at_trx_commit=2 for safe non-banking workloads, and the magento user with SUPER or log_bin_trust_function_creators=1 set persistently (not via SET GLOBAL — that does not survive a restart). Slow queries on catalog_product_entity_* EAV joins usually point to a stale catalog_product_flat or missing flat tables; turn on the flat catalog only if your store has fewer than ~5,000 SKUs.

Redis or Valkey is non-negotiable for sessions and the default cache backend. The file cache backend is a death sentence on any store with more than 50 concurrent users. Run two separate Redis databases — one for sessions, one for cache — and add a third for the page cache if you are not on Varnish. Configure maxmemory-policy=allkeys-lru on the cache database and noeviction on the session database.

OpenSearch 2.x replaced Elasticsearch in Magento 2.4.6+. The common failure mode here is leaving the default JVM heap at 1GB on a catalogue with 50,000 SKUs and faceted search. Bump it to 4–8GB and watch your category-page TTFB drop by 300ms.

Extension bloat — the silent killer

Extension bloat is the single largest source of latency I find on real client stores, and it is the hardest to diagnose because the symptoms look like server problems. A typical Magento store I audit has 40 — 60 installed modules. Of those, maybe 20 are core, 10 are vendor-maintained marketplace extensions, and the rest are accumulated debt — abandoned vendors, modules from the previous developer, extensions installed for a feature that was removed two years ago but never uninstalled.

Every extension contributes to three slowdowns. First, every di.xml entry adds a node to the dependency-injection graph that is walked on every object instantiation. Second, every plugin (interceptor) wraps a target method, and Magento generates a chain class at compile time that calls each plugin in sort-order. A method with 12 plugins runs 12 times the wrapping overhead even when no plugin actually modifies the result. Third, every event observer is loaded and invoked on every event dispatch, even when the observer immediately returns.

The fix is mechanical. Run bin/magento module:status, identify every module you do not actively use, and disable it via bin/magento module:disable. Then run composer remove for modules whose vendor packages you do not need on disk. Recompile DI. Measure TTFB before and after — I routinely cut 200–400ms off TTFB by removing 6 — 10 dead modules. The mage2kishan/module-error-monitor module I ship surfaces interceptor latency at request time so you can see which plugin is the actual offender, not the one you suspect.

The other extension trap is the "free" extension that injects a remote JavaScript on every page (chat widgets, analytics, affiliate trackers). Move every one of those to GTM with a defer attribute, or to a customer-data section that fires after the main thread is idle.

Frontend tier: RequireJS, Knockout, KO templates, image bloat

The frontend tier is where Luma stores hit a hard ceiling that no server-side tuning can break. On a Luma mobile page, RequireJS fetches roughly 150 — 200 individual JavaScript files in waterfall, taking about 6 seconds of main-thread time before the page is fully interactive. The hero text is the LCP element. With a render delay of 5.4 seconds, you cannot get LCP under 6 seconds on Luma without removing RequireJS entirely. That is exactly what Hyvä does — it strips RequireJS and Knockout.js from the frontend stack, replacing them with Alpine.js and Tailwind CSS.

If you cannot move to Hyvä yet, there are honest middle-ground wins. First, remove Font Awesome and any icon CDN — replace inline icon SVGs from the WYSIWYG. Second, defer Microsoft Clarity, GTM, and any chat widget. On a Luma store this saves about 1.2 seconds of TBT. Third, audit your requirejs-config.js for shim entries pointing to dead modules. Fourth, ensure require.js itself is loaded synchronously — deferring it breaks PageBuilder's inline require.config() bootstrap and you will see "require.config is not a function" page errors.

Image bloat is the other frontend killer. Magento 2.4.9 supports WebP product image generation natively. Run the image media generator and switch the WYSIWYG image picker to WebP-by-default. Set fetchpriority="high" on the LCP product image. Lazy-load every below-the-fold image with loading="lazy" and a width/height pair to prevent CLS. None of this fixes the RequireJS ceiling, but on Hyvä these wins compound.

Indexer + caching — when these go wrong everything goes wrong

Magento has nine indexers. When one is stuck in Processing state with no process actually running, every category page query falls back to a live EAV join instead of reading from the flat index. TTFB jumps from 200ms to 1.8 seconds. The fix is bin/magento indexer:reset followed by bin/magento indexer:reindex — and a check that no patch is holding a row lock on patch_list.

Full Page Cache (FPC) and Varnish are the difference between a fast store and a slow one for anonymous traffic. Magento ships with a built-in FPC backed by Redis. Varnish 7.x is faster but adds an operational layer. Either way, the rule is the same: every cacheable block must avoid per-customer server-side rendering. Cart counts, customer name, login state — all of that goes through the customer-data section JavaScript layer that fires after the page renders. If you put $customerSession->getCustomer()->getName() directly into a cacheable="true" block, you have poisoned the FPC.

The third trap is Cloudflare or any CDN in front of Magento that caches a 404 as aggressively as a 200. When a media URL 404s because of a perms problem on pub/media, the CDN edge caches that 404. After you fix the perms, you have to either purge the URL or version-bust it with ?v=2. I have lost hours debugging this — now I always chmod -R a+r pub/media immediately after any media import.

Reindex panth_seo_resolved_meta after CMS edits if you use the AdvancedSeo module, or your <title> tag will stay stale and show the brand name only.

Why Hyvä is the biggest single speed win

Hyvä is the biggest single speed win available to a Magento 2 store today, full stop. Switching from Luma to Hyvä replaces the entire frontend layer — Knockout.js, RequireJS, the LESS compilation pipeline, the jQuery global, the underscore.js dependency — with Alpine.js, Tailwind CSS, and ESM-style modules loaded directly from <script type="module">. The result on a representative product page is mobile Lighthouse moving from 30 — 50 on Luma to 85 — 95 on Hyvä, with mobile LCP dropping from 5 — 6 seconds to 1.5 — 2.5 seconds.

That is not a marketing claim, it is the consistent outcome I see on every Luma → Hyvä migration playbook I run. The catch is that Hyvä is a complete frontend rewrite. Every Luma-only extension needs a Hyvä-compatible counterpart, a custom Hyvä module, or a fallback compatibility module. Hyvä has a paid licence (around €1,000 one-time per domain) but the migration time is the larger investment.

If you are on Magento Open Source and price-sensitive, Mage-OS Breeze is the free alternative — a Hyvä-inspired frontend theme maintained by the Mage-OS community fork. It is not feature-equivalent to Hyvä yet, but it removes RequireJS and Knockout and delivers most of the Lighthouse win.

If you want concrete numbers for your store, run my Hyvä compatibility checker against your extension list — it tells you which extensions have official Hyvä-compatible builds.

Magento performance checklist — the 10-step audit

This is the exact 10-step audit I run on every performance engagement. Run it in order. Each step assumes the previous one is clean.

  1. Verify PHP version is 8.1 — 8.4. OPcache on. JIT off. realpath_cache_size=10M.
  2. Verify Redis or Valkey is configured for both cache and session. File cache is a fail.
  3. Verify OpenSearch is reachable, JVM heap sized to at least 4GB on stores over 10k SKUs.
  4. Run bin/magento indexer:status — every indexer must be Ready.
  5. Run bin/magento cache:status — every cache type must be Enabled.
  6. Confirm FPC or Varnish is warm. Anonymous TTFB should be under 200ms.
  7. Run bin/magento module:status. Disable and remove dead modules. Recompile DI.
  8. Audit requirejs-config.js for dead shim entries. Drop them.
  9. Run mobile Lighthouse. If LCP > 4s on Luma, your only real fix is Hyvä.
  10. Re-test after every fix. If you change two things at once you cannot attribute the win.

If you would rather I run this audit for you, I offer it as a Magento performance optimization service — fixed-fee $499 audit with a written report, or a $2,499 sprint that ships the fixes too. Adobe-Certified Magento + Hyvä developer since September 2021.

Frequently asked questions

Why is my Magento store so slow on mobile?

On Luma, mobile slowness is dominated by RequireJS main-thread cost — around 6 seconds of JavaScript work before the page is interactive. The only real fix is migrating to Hyvä, which removes RequireJS entirely. Server tuning, image optimisation, and CSS critical path work each save 100 — 500ms, but they will not get you under 4s LCP on Luma.

Is Magento slow by default?

Magento is not slow by default — a vanilla Magento 2.4.9 install with Redis, OpenSearch, FPC, PHP 8.3 and Hyvä hits 90+ Lighthouse mobile. Magento is slow when extension debt accumulates, when the server tier is misconfigured, or when the store is on Luma in 2026.

What is the fastest way to speed up Magento?

The fastest single change is moving the cache backend from file to Redis or Valkey — that alone can cut TTFB in half. After that, audit your installed modules and disable everything you do not use. Then look at the frontend.

Does Hyvä actually make Magento faster?

Yes, measurably. On every Luma to Hyvä migration I have run, mobile Lighthouse moves from the 30 — 50 range to the 85 — 95 range. LCP drops from 5 — 6 seconds to 1.5 — 2.5 seconds. The reason is that Hyvä removes RequireJS and Knockout.js — Luma's two biggest main-thread costs.

How do I find which extension is slowing Magento down?

Enable Magento's profiler in app/etc/config.php ('profiler' => 1), then load a page with ?profile=1. The profiler output shows which interceptor chains are taking the most wall time. I also ship a Panth_ErrorMonitor module that surfaces slow interceptors at request time.

Is my hosting making Magento slow?

Possibly. If your TTFB is over 800ms with FPC warm and indexers green, the bottleneck is downstream of the cache — either MySQL, an interceptor chain, or a slow API call from a third-party extension. If TTFB is over 800ms on a cold (uncached) page, your server tier is undersized — likely PHP-FPM pool exhaustion or MySQL buffer pool too small.

What is a good TTFB for Magento?

Anonymous cached page: under 200ms is the target, under 400ms is acceptable. Logged-in or cart page (uncacheable): under 800ms is good, under 1.2s is acceptable. Anything over 1.5s on either type indicates a server-tier or extension problem.

Does Cloudflare make Magento faster?

Cloudflare helps with edge delivery of static assets and TLS termination, but it does not cache HTML by default — Magento's FPC or Varnish still does the heavy lifting. Be careful with Cloudflare caching 404 responses just like 200s; after fixing a media perms issue, you need to purge the cached 404 or version-bust the URL.

Is Magento 2.4.9 faster than older versions?

Yes. Magento 2.4.9 ships with OpenSearch 2.x, PHP 8.3 support, and a number of indexer improvements over 2.4.4. The 2.4.9 upgrade guide covers the migration steps. If you are on 2.4.4 or older, upgrading is part of every speed engagement.

Should I use Varnish or FPC for Magento?

Varnish 7.x is faster than the built-in FPC on the same hardware — roughly 50 — 100ms TTFB lower. But it adds operational complexity (VCL config, cache invalidation hooks). For most stores under 50k orders/month, the built-in FPC on Redis is the right call.

Magento store running slow? I will audit it and tell you exactly what is broken. Fixed-fee from $499 audit · $2,499 sprint · ~20h @ $25/hr.

Book a performance audit