Insights
Why Is Magento Slow? A Diagnostic Checklist for Store and Admin
Magento is usually slow because the full page cache is off or being bypassed, the cache and sessions are not in Redis or Valkey, indexers or cron are not working properly, or the store is not in production mode. After those come heavy extensions, an unhealthy search service, a heavy theme, bot traffic and, last, a server that is too small. Work through the checklist below in order: the cheapest fixes are near the top, and a slow admin or a slow checkout has its own section.
The diagnostic checklist
Run the commands from your Magento root, as the user that owns the Magento files, and try any change on a staging copy first.
- Is the store in production mode? Run
bin/magento deploy:mode:show. - Are all cache types enabled? Run
bin/magento cache:statusand look for any type showing 0, especiallyfull_page. - Is the full page cache on Varnish, and is it being hit? Check the caching application in the admin and the hit rate in Varnish.
- Are the cache and sessions in Redis or Valkey, rather than on disk?
- Are the indexers valid and on Update by Schedule? Run
bin/magento indexer:statusandbin/magento indexer:show-mode. - Is cron running? Run
crontab -land check thecron_scheduletable. - Is OpenSearch healthy and given enough memory?
- Is an extension doing too much work? Profile a slow page.
- Are images, JavaScript and the theme heavy?
- Are bots and crawlers taking capacity? Check the access log.
- Is the server simply too small? Only once the points above are sorted.
Full page cache off or bypassed
If the full page cache is off or bypassed, Magento builds every page from scratch, and in our experience this is the most common cause of a slow Magento store.
The full page cache stores finished public pages, such as category, product and CMS pages, so most visitors never wait for PHP. Check it is enabled with bin/magento cache:status; the full_page line should show 1. For a live store, Adobe says "We strongly recommend you use Varnish in production". The built-in cache works, but Adobe calls it much slower. The setting is under Stores > Settings > Configuration > Advanced > System > Full Page Cache.
A full page cache can be switched on and still do little. Two things to look for:
- Uncacheable blocks. Adobe's frontend guide says "If any block in a layout is designated as uncacheable, the entire page is uncacheable." One extension that adds
cacheable="false"to a layout block on a product or category page sends every visit to that page back to PHP. Search your custom code and extensions for it, for examplegrep -rn 'cacheable="false"' app/code app/design vendor. Adobe's advice is never to make catalog, product or CMS pages uncacheable. - A low hit rate. Varnish's own
varnishstattool shows cache hits against misses. A hit rate that stays low usually means pages are being marked uncacheable, the cache is being cleared too often, or URLs carry parameters that turn one page into many different cache entries.
Customer-specific parts of a page, such as the basket and the customer's name, are not in the full page cache. Adobe's private content model loads them in the browser after the page arrives, so a cached page can still show the right basket. Checkout and the basket themselves are not cached at all; by default, Adobe says, "all pages are cacheable except the checkout pages". More on how this works in Varnish cache for Magento.
Cache and session storage: Redis or Valkey
Magento's cache and customer sessions should sit in an in-memory store, Redis or Valkey, rather than in files on disk.
On current Magento releases, Adobe requires Valkey rather than Redis for the cache: from 2.4.9, and from the patch releases after 2.4.5-p16, 2.4.6-p14, 2.4.7-p9 and 2.4.8-p4. Older releases use Redis. Adobe recommends keeping the default cache, the page cache and sessions apart, using separate databases or instances, so that clearing one does not empty the others. See Valkey for Magento and Redis and OpenSearch for Magento.
Redis vs Varnish: which does Magento 2 need?
Both, because they do different jobs. Varnish sits in front of Magento and serves whole public pages without running PHP. Redis or Valkey sits behind Magento and holds its internal cache, such as configuration and layout, plus customer sessions. One does not replace the other.
Full page cache in Redis or Valkey
Magento can store its built-in full page cache in Redis, or Valkey on newer versions, instead of in files. That is better than files, but it is still Magento's built-in cache, and Adobe's recommendation for production is Varnish. Redis or Valkey for the page cache suits stores that cannot run Varnish.
Redis session locking
PHP locks a customer's session while one request uses it, so a second request from the same visitor waits. That protects session data, but on pages that fire several requests at once, especially in the admin, the waits add up. Adobe documents settings for this: the maximum number of processes that can wait for one session's lock, how long frontend and admin requests wait before breaking the lock, and an option to disable locking entirely. On Redis they are set with flags such as --session-save-redis-max-concurrency and --session-save-redis-disable-locking; from 2.4.9 the flags use valkey in place of redis. Changing them is a trade-off between speed and session safety, so test on staging and change one thing at a time.
How to flush the Redis or Valkey cache
Use Magento's own command: bin/magento cache:flush empties the cache storage Magento is configured to use. Adobe's debugging guide also shows flushing one Redis database directly with redis-cli -n <db_number> FLUSHDB, and labels redis-cli FLUSHALL as flushing the cache and sessions; it marks both "do not run on production environments". In our experience, a FLUSHALL on an instance that also holds sessions signs every customer and admin user out. On Valkey the tool is valkey-cli.
Indexers on the wrong mode
Indexers on "Update on Save" make every admin save slower and can load the database at busy times; "Update by Schedule" moves the work into the background.
Magento's indexers turn your catalogue, prices and stock into fast lookup tables. On Update on Save (realtime), each change is indexed immediately as it is saved. On Update by Schedule (schedule), changes are logged and cron indexes them in the background. Adobe advises: "Set the indexers to Update on Schedule for large sites, and sites with frequent updates and heavy traffic." Since 2.4.8, Update by Schedule is the default.
bin/magento indexer:status
bin/magento indexer:show-mode
bin/magento indexer:set-mode schedule
bin/magento indexer:reindexAdobe recommends putting the store into maintenance mode and pausing cron before you change indexer modes, so plan it for a quiet window. One version catch: before 2.4.8, the Customer Grid indexer could only use Update on Save. From 2.4.8 it supports both modes.
Update by Schedule depends entirely on cron. If cron stops, the index falls behind, and prices, stock or new products stop updating on the store front.
For every indexer command and how to fix stuck indexes, see Magento 2 reindex and indexers.
Asynchronous indexing in Magento 2
"Asynchronous indexing" in Magento usually means one of two things. The first is Update by Schedule, above. The second is a separate setting for the admin's order, invoice, shipment and credit memo grids: with asynchronous grid indexing on, placing an order no longer waits for those grids to update, and cron updates them shortly after. In production mode the Developer tab that holds this setting is hidden, so set it from the command line:
bin/magento config:set dev/grid/async_indexing 1Cron must be running for the grids to update.
Cron not running or stuck
If Magento cron is not running, indexes go stale, emails and queued jobs pile up, and the store slowly drifts out of date without an obvious error.
To check cron, Adobe suggests looking at the crontab as the Magento file system owner and at the cron_schedule table:
crontab -l
bin/magento cron:installcrontab -l should show Magento's entries; if it doesn't, bin/magento cron:install adds them. Then look at recent jobs in the database:
SELECT job_code, status, scheduled_at, executed_at, finished_at
FROM cron_schedule
ORDER BY scheduled_at DESC
LIMIT 20;The status column shows each job's state: pending, running, success, missed or error. Lots of missed jobs mean cron isn't firing often enough or a job is overrunning. Jobs stuck on running for hours usually mean a job died part way through; Adobe has a knowledge base article on clearing them. Errors show the message in the same table. Adobe gives var/log/cron.log as the default cron log, and the crontab that cron:install writes sends its output to var/log/magento.cron.log.
You can run cron by hand to test it, for example bin/magento cron:run --group=index for the indexing jobs. Cron also restarts Magento's message queue consumers through the consumers_runner job, which bulk actions and some asynchronous operations rely on.
For a full walk-through, see Magento 2 cron not running?
Developer mode in production
A live store should run in production mode; Adobe says production mode "has better performance because static view files are populated in the pub/static directory and because of code compilation."
bin/magento deploy:mode:show
bin/magento deploy:mode:set productionSwitching to production mode compiles code and deploys static files, so the store goes into maintenance while it runs. Do it on staging first and expect errors that developer mode was hiding.
Heavy or badly written extensions
Extensions are the usual cause when the cache and server are healthy but certain pages are still slow.
Find out where the time goes before removing anything. Magento has a built-in profiler:
bin/magento dev:profiler:enable html
bin/magento dev:profiler:disableIt records how long each part of a page takes to build. Use it on staging, not on the live store, and switch it off afterwards. An application performance monitoring (APM) tool does the same job continuously in production, showing the slowest transactions, database queries and external calls. The database's slow query log is the other place to look. Common culprits are extensions that run heavy queries on every page, call external services while the page waits, observe busy events, or make blocks uncacheable.
On staging, disabling suspect modules one at a time with bin/magento module:disable Vendor_Module confirms the culprit. The fix itself is a code change for your developer or the extension's vendor.
OpenSearch sizing and health
Catalogue search and layered navigation run through OpenSearch, so an unhealthy or memory-starved search service slows category pages and search results.
Check the cluster's health from the server with curl -s 'localhost:9200/_cluster/health?pretty' (adjust the host and port to your setup). OpenSearch defines red as at least one primary shard unassigned, so some data can't be reached. Yellow means some replica copies are unassigned, which on a single-server setup usually just means there is no second node to hold them. Beyond health, OpenSearch needs its own memory: on a small server it competes with PHP and the database, and it is often left on default settings that don't suit the catalogue.
OpenSearch vs Elasticsearch for Magento 2
OpenSearch is the open-source search engine that grew out of Elasticsearch, and it is now Adobe's direction for Magento. Adobe's on-premises requirements list only OpenSearch 3 for Magento 2.4.9. For 2.4.8 the requirements table still lists Elasticsearch 8, but Adobe's 2.4.8 release notes say its Elasticsearch modules are deprecated. A store planning to upgrade should move to OpenSearch. More in Redis and OpenSearch for Magento.
Images, JavaScript and the theme
Even a fast server can't make a heavy front end feel quick, because much of what visitors notice happens in the browser.
Oversized images, large JavaScript bundles, web fonts and third-party tags such as chat, reviews and tracking all slow the page down after the server has done its part. Magento's default Luma theme loads a lot of JavaScript. Hyvä is a lighter front end built to reduce that; see our guide to Magento Hyvä theme hosting. For how this affects Core Web Vitals, see Magento performance optimisation. For a CDN in front of the store, we recommend Cloudflare.
Bots and crawler floods
Aggressive crawlers and bots can take a large share of a server's capacity, and they tend to hit the pages the cache can't help with.
Search results are never cached, and filtered category URLs come in endless combinations, so most of them are not in the cache. A crawler working through them lands on PHP almost every time. Look at the busiest IP addresses and user agents in your web server's access log, for example:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | headWell-behaved crawlers follow robots.txt; abusive ones don't, and have to be blocked at the server or at a CDN. Our guide on how to block AI crawlers on Magento 2 covers the rules. On EveryHost servers, Sentinel reads the server's logs and blocks abusive sources at the server firewall; it is not a web application firewall or a CDN.
The server is too small
Upgrade the server only once the points above are sorted; if CPU or memory still stays high under normal traffic, the store has outgrown it.
Signs include the PHP-FPM log warning that the pool has reached its maximum number of children, the server using swap, OpenSearch running short of memory, and slowdowns that follow traffic rather than any one page. A bigger server buys little if the cache is being bypassed or an extension is the bottleneck, so measure first. Our Magento server calculator gives a starting point.
Why the Magento admin is slow
The Magento admin is never served from the full page cache, so it shows every database, indexer, session and extension problem directly.
When only the admin panel is very slow, check these first:
- Indexers on Update on Save, which make every product save wait for reindexing. Move them to Update by Schedule.
- Synchronous grid indexing, which makes orders and the sales grids slower. Turn on asynchronous grid indexing.
- Session locking, when several admin requests from the same user queue behind one another.
- Large grids. Grids showing hundreds of rows, or many columns from extensions, run heavy queries. Show fewer rows and remove columns you don't use.
- Cron and message queues. Bulk actions, such as mass attribute updates, run through message queue consumers that cron starts. If cron is down, they never finish.
- Admin extensions. Some extensions add dashboards, notifications or checks to every admin page. The profiler shows them.
Why Magento checkout is slow
Checkout is never served from the full page cache, so it depends on PHP, the database, sessions and any payment, shipping or tax services it calls while the customer waits.
A slow checkout with a fast homepage is normal, and fixing it means looking at the logged-in journey rather than the cached pages. We cover this in detail, including how it behaves under peak load, in Magento checkout speed at peak.
How to clear Magento cache
Use bin/magento cache:clean for everyday cache clearing, and bin/magento cache:flush only when cleaning hasn't fixed the problem.
bin/magento cache:clean
bin/magento cache:flushThe difference, in Adobe's words: "Cleaning a cache type deletes all items from enabled Commerce cache types only", while "Flushing a cache type purges the cache storage, which might affect other processes" using the same storage. Adobe suggests you flush only if you have "already tried cleaning the cache" and still have problems. You can name cache types, for example bin/magento cache:clean full_page. In the admin, the same actions are under System > Cache Management.
When Varnish is set up with Magento's purge settings (bin/magento setup:config:set --http-cache-hosts=...), Adobe says that "when you clean, flush, or refresh the Commerce cache, Varnish purges as well". There is no need to restart Varnish. If the cache uses Redis or Valkey, use these commands rather than flushing the Redis or Valkey database by hand, for the session reason above.
Summary: symptom, cause and fix
| Symptom | Likely cause | Where to check | Fix |
|---|---|---|---|
| Every page slow, even repeat visits | Full page cache off or on the built-in cache | bin/magento cache:status; Stores > Configuration > Advanced > System > Full Page Cache | Enable full_page and use Varnish |
| Some product or category pages always slow | A block marked cacheable="false" | Layout XML in custom code and extensions | Remove it or move the content to private content; developer fix |
| Low Varnish hit rate | Uncacheable pages, frequent cache clears, tracking parameters | varnishstat | Find the cause before adding capacity |
| Slow pages under load, sessions or cache on disk | No Redis or Valkey | app/etc/env.php | Move cache and sessions to Redis or Valkey |
| Admin requests queue behind each other | Session locking | Session settings in app/etc/env.php | Tune locking settings on staging |
| Admin saves very slow | Indexers on Update on Save | bin/magento indexer:show-mode | bin/magento indexer:set-mode schedule |
| Prices, stock or new products not updating | Cron not running or stuck | crontab -l; cron_schedule table; var/log/cron.log | bin/magento cron:install; clear stuck jobs |
| Orders and sales grids slow | Synchronous grid indexing | dev/grid/async_indexing | bin/magento config:set dev/grid/async_indexing 1 |
| Whole store sluggish, errors shown in detail | Developer mode | bin/magento deploy:mode:show | bin/magento deploy:mode:set production on staging first |
| Certain pages slow with a healthy cache | Heavy extension | Profiler, APM tool, slow query log | Developer or vendor fix |
| Search and category filters slow | OpenSearch unhealthy or short of memory | Cluster health; server memory | Give OpenSearch the memory it needs |
| Fast server, slow-feeling pages | Images, JavaScript, theme, third-party tags | Browser developer tools; Core Web Vitals | Lighter theme, smaller images, fewer tags |
| Load spikes not matched by sales | Bots and crawlers | Web server access log | robots.txt, server-side blocking, a CDN |
| High CPU or memory after all the above | Server too small | PHP-FPM log, swap, monitoring | Move to a bigger server |
| Checkout slow, rest of store fine | Uncached checkout, sessions, third-party calls | Logged-in journey under load | See the checkout speed guide |
Need a hand?
If you've worked through the checklist and your store is still slow, we can help. We tune the server layer on our servers in our London data centre, tell you honestly what is server and what is code, and pass code findings to your developer. See Magento performance optimisation and our plans and prices.
Sources
All accessed 13 October 2026.
- Adobe: Manage the cache
- Adobe: Use Varnish cache
- Adobe: Configure Varnish
- Adobe: Page caching (frontend guide)
- Adobe: Full page caching and private content
- Adobe: Use Redis for session storage
- Adobe: Use Valkey for session storage
- Adobe: Use Valkey for the default and page cache
- Adobe: Debugging best practices
- Adobe: Manage the indexers
- Adobe: Indexer configuration best practices
- Adobe: Performance best practices, configuration
- Adobe: Configure and run cron
- Adobe: Cron job stuck in running status
- Adobe: Manage message queues
- Adobe: Set the application mode
- Adobe: Enable the profiler
- Adobe: System requirements
- Adobe: Magento Open Source 2.4.8 release notes
- Adobe: Software recommendations
- OpenSearch: Cluster health API
Frequently asked questions
Still slow after the checklist?
Tell us what feels slow and we will tell you honestly whether it is the server, the code or the theme.