Magento 224 April 20268 min read

Magento 2 Indexer Stuck: How to Diagnose and Fix Stuck or Invalid Indexers

Ostoya Engineering

Verified Technical Lead

Executive Summary

Is your Magento 2 indexer showing 'working' or 'invalid' indefinitely? This is the diagnostic process and fix for stuck indexers — without causing downtime on a live store.

Magento 2 Indexer Stuck: Diagnosis and Fix

If you have ever opened System → Index Management and found an indexer permanently showing Working or Invalid — hours or days after it should have finished — you are dealing with one of the most common and frustrating operational problems in Magento 2.

The symptoms are consistent:

  • Catalogue changes are not appearing on the storefront
  • Price updates are not going live
  • Category page products are stale
  • Running bin/magento indexer:status shows working indefinitely
  • Running bin/magento indexer:reindex either hangs or exits silently

This post walks through why this happens, how to safely diagnose the root cause, and how to fix it without causing downtime on a live store.


Why Magento Indexers Get Stuck

Magento indexers work by processing a queue of changes tracked in changelog tables (for Update by Schedule mode) or by running a full reindex on demand. A stuck indexer means the process that was processing the queue either crashed, ran out of memory, or was killed — without properly releasing its lock.

The three most common root causes are:

  1. A previous reindex process was killed mid-run (server restart, OOM kill, deployment script)
  2. A cron job that triggers indexing died without cleanup
  3. A deadlock or memory exhaustion during a large reindex

The indexer records a started_at timestamp in the indexer_state table when it begins. If the process dies before it can write the finished_at value, Magento sees an in-progress run and refuses to start another one — forever.


Step 1: Confirm the Indexer Is Genuinely Stuck

First, check the current status:

BASH
bin/magento indexer:status

You will see output like:

BASH
+----------------------+------------------+-----------+---------------------+---------------------+
| Title                | Status           | Update On | Schedule Status     | Schedule Updated    |
+----------------------+------------------+-----------+---------------------+---------------------+
| Product Price        | Working          | Schedule  | running (0 backlog) | 2026-04-23 14:22:01 |
| Catalog Product Rule | Reindex required | Schedule  | idle                | 2026-04-23 14:22:01 |
+----------------------+------------------+-----------+---------------------+---------------------+

If the Working status has not changed in more than 15–20 minutes, it is stuck.

Now check whether there is actually a live reindex process running:

BASH
ps aux | grep magento

If you see an active indexer:reindex process — wait for it. If nothing is running, the process has died and left the lock behind.


Step 2: Check the Database Lock Directly

The indexer state is stored in the indexer_state table. Query it:

SQL
SELECT indexer_id, status, updated, hash_config
FROM indexer_state
WHERE status = 'working';

If rows come back with a status of working but no live process is running, those are ghost locks that need clearing.

Also worth checking the mview_state table, which tracks the changelog view status:

SQL
SELECT view_id, mode, status, updated, version_id
FROM mview_state
WHERE status = 'working';

Step 3: Check for OOM Kills and Crash Evidence

Before clearing the lock, understand why the indexer died. Check the system logs:

BASH
# Check for OOM kills
sudo dmesg | grep -i 'killed process'
 
# Check PHP-FPM logs
sudo tail -100 /var/log/php-fpm/error.log
 
# Check Magento exception log
tail -100 var/log/exception.log
 
# Check Magento system log
tail -100 var/log/system.log

Common things you will find:

  • Out of memory: Kill process — the server killed the PHP process during a large reindex
  • Maximum execution time exceededmax_execution_time in php.ini is too low for large catalogues
  • Deadlock found when trying to get lock — a database deadlock killed the transaction

Fix the root cause first

Do not just clear the lock and reindex without understanding why it failed. If you clear without fixing, it will fail again — possibly causing data inconsistencies on the storefront.


Step 4: Fix the Root Cause

If the cause is OOM (Out of Memory)

Increase PHP memory for CLI processes. This is separate from the webserver PHP configuration:

BASH
# Check current CLI memory limit
php -i | grep memory_limit
 
# Override for a single reindex run
php -d memory_limit=2G bin/magento indexer:reindex

For a permanent fix, update your php.ini or create a CLI-specific override:

INI
; /etc/php/8.3/cli/conf.d/99-magento.ini
memory_limit = 2G
max_execution_time = 3600

If the cause is max_execution_time

For CLI scripts, max_execution_time should be 0 (unlimited). Confirm:

BASH
php -r "echo ini_get('max_execution_time');"

If this returns anything other than 0, override it in your CLI php.ini.

If the cause is a database deadlock

A deadlock usually means two processes were writing to the same tables simultaneously. Check whether you have overlapping cron jobs:

SQL
SELECT job_code, status, scheduled_at, executed_at, finished_at
FROM cron_schedule
WHERE status = 'running'
ORDER BY executed_at DESC
LIMIT 20;

If you see multiple indexer_reindex_all_invalid jobs with running status and no finished_at, your cron schedule is overlapping. This usually means the cron run interval is too short for your catalogue size, or cron is misconfigured to run more frequently than intended.


Step 5: Clear the Stuck Lock

Once you have identified and addressed the root cause, clear the ghost lock from the database.

Take a database backup first

Always back up your database before manually modifying indexer state tables. On a large catalogue this is critical.

Reset the stuck indexer state:

SQL
-- Reset all stuck indexers
UPDATE indexer_state SET status = 'invalid' WHERE status = 'working';
 
-- Or reset a specific indexer only (safer)
UPDATE indexer_state SET status = 'invalid'
WHERE indexer_id = 'catalog_product_price'
AND status = 'working';

Reset stuck mview states:

SQL
UPDATE mview_state SET status = 'idle' WHERE status = 'working';

Step 6: Reindex Safely

After clearing the lock, reindex the affected indexers. Do not reindex everything at once on a live store with a large catalogue — it will hit the same memory and deadlock problems.

Reindex individual indexers instead:

BASH
# List all indexers
bin/magento indexer:status
 
# Reindex a single indexer
bin/magento indexer:reindex catalog_product_price
 
# Reindex multiple specific indexers
bin/magento indexer:reindex catalog_product_price catalogsearch_fulltext

If you need to reindex everything and your catalogue is large, run each indexer separately with a gap between them to reduce database pressure:

BASH
for indexer in catalog_category_product catalog_product_category catalog_product_price catalogsearch_fulltext; do
    echo "Reindexing: $indexer"
    php -d memory_limit=2G bin/magento indexer:reindex $indexer
    echo "Done: $indexer"
    sleep 5
done

Step 7: Verify and Flush Cache

After reindexing completes:

BASH
# Confirm all indexers are valid
bin/magento indexer:status
 
# Flush cache
bin/magento cache:flush
 
# Or flush specific cache types
bin/magento cache:clean full_page block_html

Preventing It From Happening Again

Switch to Update by Schedule

If you are running indexers in Update on Save mode, every product or price change triggers a synchronous reindex during the admin save operation. This is slow and increases the risk of timeouts. Switch to Update by Schedule:

BASH
bin/magento indexer:set-mode schedule

This queues changes in changelog tables and processes them via cron, which is much safer for catalogues with more than a few hundred products.

Clean the cron_schedule Table Regularly

The cron_schedule table accumulates rows over time and can slow cron execution significantly:

SQL
-- Check table size
SELECT COUNT(*) FROM cron_schedule;
 
-- Delete old completed/failed rows (safe to run during low traffic)
DELETE FROM cron_schedule
WHERE status IN ('success', 'missed', 'error')
AND scheduled_at < DATE_SUB(NOW(), INTERVAL 7 DAY);

Monitor Indexer Status

Add indexer status to your monitoring. A simple cron-driven check that alerts when any indexer has been in working state for more than 30 minutes will catch this before it becomes a customer-facing issue.


The Indexer Reference

Indexer IDWhat It DoesImpact When Stuck
catalog_category_productCategory → product assignmentsWrong products in categories
catalog_product_categoryProduct → category assignmentsProducts missing from nav
catalog_product_priceProduct pricingStale prices on storefront
catalog_product_attributeLayered nav attributesFilters broken
catalogsearch_fulltextSearch indexSearch returns no results
catalogrule_ruleCatalogue price rulesPromotions not applying
catalogrule_productCatalogue price rule productsPromotion prices not showing
customer_gridAdmin customer gridAdmin search broken
design_config_gridDesign configAdmin design settings

When to Call It

If you have followed all of the above and indexers are still failing repeatedly, the problem is usually one of three things:

  • Catalogue data quality — corrupted or malformed product records that cause the indexer to fail mid-run. Run bin/magento catalog:images:resize and check for errors as a proxy.
  • Extension conflict — a third-party module is observing indexer events and throwing exceptions that kill the process silently. Check var/log/exception.log carefully during a reindex attempt.
  • Infrastructure limits — the server genuinely does not have enough RAM or MySQL buffer pool size for your catalogue. This requires a hosting review.

If your indexers are failing repeatedly and the above has not resolved it, it is worth a proper technical audit of your environment before the problem cascades into other operational issues.

For professional support, see our Magento support retainers or if releases and operations are breaking more broadly, Magento project rescue.

Need help with Magento?

Planning Magento for your small business or start-up?

We help brands choose the right platform, launch lean Magento builds, and scale without wasting budget.

Related services: Magento project rescue, Hyvä and performance optimisation, and marketplace operations.

Book a Technical Assessment

Free 20-minute call · No hard sales, ever.