Your Magento store is slow for a small number of predictable reasons, and almost all of them live on the backend, not in the browser. In practice the eight repeat offenders are N+1 database queries, a full-page cache (FPC/Varnish) that is disabled or being bypassed, indexers stuck on "update on save", a misconfigured Redis or session backend, third-party module bloat and conflicts, under-provisioned or untuned hosting (OPcache and PHP-FPM), a frontend theme that has hit its ceiling (Luma's JavaScript weight and poor INP), and a high TTFB caused by real work happening inside the request path. The hard part is knowing which ones apply to your store - that is exactly what a performance audit is for.
1. N+1 database queries
The classic Magento slowdown: a page that loads one product fires one query, but a page that loads 40 products fires 40 extra queries - one per item - because a module loads data inside a loop instead of in a single collection call. You will not catch this in a synthetic homepage test; it surfaces on category pages, cart, and checkout as the catalog and traffic grow.
- Symptom - response time scales with the number of items on the page; MySQL CPU spikes under catalog and checkout load.
- Fix direction - profile with Blackfire or Xdebug, find the query issued inside a loop, and replace it with a single collection load or a joined query. Poorly written third-party modules are the usual source.
2. Full-page cache or Varnish disabled or misconfigured
Magento's full-page cache is the single biggest lever for anonymous traffic. When it is off, set to the built-in cache instead of Varnish, or silently bypassed, every page renders from scratch on every request. A stray Cache-Control: no-cache header, a session started on cacheable pages, or a module that disables FPC "to be safe" will quietly gut your performance.
- Symptom - TTFB is high even on a warm homepage; response times barely differ between logged-in and anonymous users.
- Fix direction - confirm Varnish is the FPC backend, verify hit rates, and hunt down the header or block that is marking pages uncacheable.
3. Indexers on "update on save" instead of "by schedule"
Magento keeps indexes (price, catalog, stock) in sync. On "update on save", every admin edit or import reindexes synchronously and can lock tables while shoppers wait. On "update by schedule", reindexing is batched through cron and kept off the request path.
- Symptom - the store crawls during imports, price updates, or bulk admin edits; the storefront stalls at seemingly random times.
- Fix direction - set all indexers to "update by schedule", confirm cron runs reliably, and check
indexer:statusfor anything stuck or invalid.
On large catalogs the category indexer becomes a bottleneck of its own, regardless of mode - see Could not acquire lock for index if reindexing hangs or dies outright.
4. Redis or session storage misconfigured
Magento uses Redis (or Valkey) for the default cache, the full-page cache, and sessions. Point sessions at the database, run a single undersized Redis instance, or let it evict keys under pressure, and you trade fast in-memory lookups for slow disk and lock contention.
- Symptom - checkout and account pages are sluggish; Redis shows high eviction rates, or the DB shows session lock waits.
- Fix direction - use Redis for sessions and cache on separate databases, size
maxmemorycorrectly, and pick a sane eviction policy. Verify the config actually took effect inapp/etc/env.php.
5. Third-party module bloat and conflicts
Every extension adds plugins, observers, and layout XML that run on requests they were never meant to touch. Ten "lightweight" modules stacked on checkout add real milliseconds per request, and two modules rewriting the same class produce conflicts that are both slow and fragile.
- Symptom - performance degraded after installing extensions; the profiler shows time spent in vendor plugins on unrelated pages.
- Fix direction - inventory installed modules, disable what you do not use, and measure each suspect plugin's cost. A Magento audit maps which extensions sit on the critical path.
6. Under-provisioned or untuned hosting
Magento is PHP, and PHP performance lives and dies by OPcache and PHP-FPM tuning. OPcache off or undersized means PHP recompiles on every request. Too few PHP-FPM workers means requests queue under load; too many means the box swaps. Shared or undersized hosting caps everything above it.
- Symptom - CPU pegged under modest traffic; response times climb sharply as concurrency rises.
- Fix direction - enable OPcache with realistic memory and file limits, tune
pm.max_childrento fit RAM, and give MySQL and Redis enough headroom. Right-size the box before optimizing code.
7. The frontend theme ceiling (Luma vs Hyva)
Even with a fast backend, the default Luma theme ships heavy JavaScript, RequireJS, and Knockout that hurt Interaction to Next Paint (INP) and Largest Contentful Paint on real devices. There is a ceiling to how fast Luma gets, no matter how well you tune the server.
- Symptom - good TTFB but poor field Core Web Vitals; sluggish interactions on mid-range phones.
- Fix direction - trim and defer JavaScript, or move to Hyva, which drops RequireJS/Knockout for a far lighter frontend and typically transforms INP and LCP.
8. High TTFB from backend work in the request path
Time to First Byte is the sum of everything above: cache misses, slow queries, blocking indexers, external API calls made synchronously during page render. A high TTFB is less a cause than the symptom that backend work is happening where the shopper has to wait for it.
- Symptom - TTFB consistently above a few hundred milliseconds on cacheable pages; slow first byte across the whole site.
- Fix direction - move slow and external work out of the request path (queues, cron, async), fix the cache, and profile the remaining hot path.
Quick reference: the 8 causes
| Cause | Symptom | Fix direction |
|---|---|---|
| N+1 database queries | Response time scales with items on the page | Load collections once, not in a loop |
| FPC / Varnish off or bypassed | High TTFB even on warm pages | Confirm Varnish backend and cache hit rate |
| Indexers on "update on save" | Store stalls during imports and edits | Switch to "update by schedule" plus cron |
| Redis / sessions misconfigured | Slow checkout, evictions, lock waits | Right-size Redis, keep sessions off the DB |
| Module bloat and conflicts | Slower after installing extensions | Audit and disable unused modules |
| Untuned hosting | CPU pegged under modest traffic | Tune OPcache, PHP-FPM, right-size the box |
| Luma frontend ceiling | Good TTFB, poor INP/LCP | Trim JS or move to Hyva |
| High TTFB | Slow first byte site-wide | Move work off the request path |
Most stores are slow for two or three of these reasons at once, and the fastest wins are almost always in the cache, the indexers, and the hosting - not a rewrite. Start by measuring, then fix in order of impact. If you want the diagnosis done for you, a broader Magento audit or a focused performance audit will pinpoint the exact bottlenecks in your store.
