Magento 2 Cron & Indexer Stuck? A Field Triage Checklist
Magento 2 cron and indexer triageĀ is a diagnostic routine for store operators and developers that gets a stuckĀ cron_scheduleĀ queue or an indexer frozen inĀ processingĀ moving again, fast, without a blind reindex.
ReadĀ cron_scheduleĀ in the DB and runĀ bin/magento indexer:statusĀ before touching anything.
A wall ofĀ missedĀ rows = the OS crontab that callsĀ cron:runĀ is dead or one long job blocks the group.
An index stuck onĀ processingĀ for hours = a stale lock (OOM-killed worker, dangling DB/Redis lock), not real work.
Know your modes:Ā Update on SaveĀ vsĀ Update by ScheduleĀ changes how a stuck index behaves.
Recovery order: reset the stuck index, clear the lock, fix the crontab, then reindex the ONE broken index.
Is cron actually running?
Magento schedules jobs intoĀ cron_scheduleĀ but relies on an OS crontab to callĀ bin/magento cron:runĀ every minute. If that is missing, jobs sit inĀ pendingĀ then age out toĀ missed.SELECT job_code, status, COUNT(*) c FROM cron_schedule GROUP BY job_code, status ORDER BY c DESC; crontab -l -u www-data | grep cron:run
Reinstall the schedule with Magento's own installer rather than hand-editing:bin/magento cron:install
What is the difference between Update on Save and Update by Schedule?
Update on SaveĀ recalculates the index the moment you save (slower saves, no cron dependency).Ā Update by ScheduleĀ only writes a row into an MView changelog table that cron consumes later (fast saves, but a stale storefront if cron dies). Put catalog, price and stock on schedule.bin/magento indexer:show-mode bin/magento indexer:set-mode schedule catalog_product_price
Why is my indexer stuck on processing?
It is waiting on a lock no live process will release, usually an OOM-killed worker (exit 137), a danglingĀ GET_LOCK()Ā DB lock, or an orphaned Redis lock key. Reset, then reindex only that index:bin/magento indexer:reset catalog_product_price bin/magento indexer:reindex catalog_product_price
If the lock backend is Redis (lock.configĀ inĀ env.php) and reset does not free it, drop the orphaned key directly withĀ redis-cli.
bin/magento indexer:status bin/magento indexer:reset catalog_product_price DELETE FROM cron_schedule WHERE status IN ('missed','error'); bin/magento indexer:reindex catalog_product_price bin/magento cache:flush
On memory-tight boxes a full reindex of all indexers is the thing that gets OOM-killed in the first place. Fix the single broken index, watchĀ top, batch the rest only once you have headroom.
I keep this in my own runbook, longer cases live on my Magento engineering blog, and the "cron died after an upgrade" pattern is what my Magento upgrade service hardens against. I'm also Kishan on Magento Stack Exchange., Adobe-Certified Magento 2 + Hyvä developer, kishansavaliya.com.