Services

Adobe Commerce development
Storefront design
Upgrades, migration & support
Performance & SEO
AI & agentic commerce
Custom application development
Book a free audit call

Magento Cron and Indexers: How They Work and How to Keep Them Healthy

Cron health check: Performance & hosting guide from Mistri
Loading...
Magento Cron and Indexers: How They Work and How to Keep Them Healthy

Magento cron is a single system crontab entry that runs bin/magento cron:run every minute. That command schedules and executes the store's background jobs: updating indexes, sending emails, generating sitemaps, applying catalog price rules and starting queue consumers. Indexers turn raw catalog data into fast lookup tables, and in "Update by Schedule" mode they depend entirely on cron. When cron stalls, prices, stock and search go stale without any visible error.

This guide explains how the two systems work together, then gives a health-check table you can run on any 2.4.x store.

How Magento cron works

Run bin/magento cron:install as the file system owner (not root). It writes a block between #~ MAGENTO START and #~ MAGENTO END comments in that user's crontab, with a schedule of * * * * *. Each run does two things:

  1. Generates a schedule. Magento reads every module's crontab.xml and writes upcoming jobs to the cron_schedule database table with a status of pending.
  2. Executes due jobs. Jobs whose scheduled time has passed move to running, then success, error or missed.

Adobe notes that cron must run twice for a new job: the first run discovers it, the second runs it. Jobs are organized into groups, mainly default and index. You can run one group for testing with bin/magento cron:run --group=index.

Group behavior is set at Stores > Settings > Configuration > Advanced > System > Cron (Scheduled Tasks): how often schedules are generated, how far ahead, when a job counts as missed, how long history is kept, and whether a group runs in a separate process. The defaults suit most stores; change them only to solve a specific problem.

Message queue consumers (used for things like bulk actions and some inventory and export tasks) are also started by a cron job unless you run them under a process manager. That behavior is controlled by the cron_consumers_runner section in app/etc/env.php.

How indexers work

Indexers precompute data the storefront needs fast: category-product links, final prices, stock, catalog rules and the search index that feeds OpenSearch. Adobe Commerce adds indexers for target rules and sales rules. Each indexer runs in one of two modes:

  • Update on Save reindexes affected rows when an entity is saved in the admin.
  • Update by Schedule uses MySQL triggers to record changed IDs in changelog tables (the indexer table name plus _cl, such as catalog_category_product_cl). A cron job then processes those changes in batches.

Adobe's Index Management documentation recommends Update by Schedule for all indexers, partly because simultaneous admin saves in Update on Save mode can cause database deadlocks. From 2.4.8 the Customer Grid indexer also supports and defaults to Update by Schedule. Since 2.4.7 you can pause automatic updates with bin/magento indexer:set-status suspended, which helps during large imports.

The Catalog Search indexer is the bridge to OpenSearch, so a stuck index shows up first as wrong search results. See our OpenSearch for Magento guide for the search side.

Health-check commands and warning signs

Run these checks after every deployment and on a regular schedule. Most stores can script them and alert on the warning signs.

CheckCommand or placeHealthyWarning sign
Crontab installedcrontab -l as the file system ownerOne Magento block, runs every minuteNo block, duplicate blocks, wrong PHP binary or old update/cron.php lines
Jobs are being executedcron_schedule grouped by statusRecent success rows every few minutesOnly pending rows, or no rows newer than a few minutes
Nothing stuckcron_schedule rows with status runningRunning rows are recentRows marked running for hours, blocking the same job
Errors and missescron_schedule with error or missed; var/log/cron.log, exception.logRare, explained errorsThe same job failing repeatedly; many missed rows (cron too slow or overlapping)
Indexer statebin/magento indexer:statusAll "Ready", small or zero backlog"Reindex required", or a schedule backlog that keeps growing
Indexer modebin/magento indexer:show-modeUpdate by Schedule for all, by designMixed modes nobody chose; Update on Save on a busy admin
Admin warningsSystem messages; System > Tools > Index ManagementNo cron or indexer messages"One or more indexers are invalid" or cron availability notices
Queue consumersbin/magento queue:consumers:list and your process managerConsumers you rely on are running or started by cronBulk actions or exports that never finish

Two read-only queries cover most of the database checks:

-- job outcomes in the current history window
SELECT job_code, status, COUNT(*) AS jobs, MAX(executed_at) AS last_run
FROM cron_schedule
GROUP BY job_code, status
ORDER BY job_code;

-- jobs that look stuck
SELECT job_code, executed_at
FROM cron_schedule
WHERE status = 'running'
ORDER BY executed_at;

Common problems and safe fixes

Cron stopped after a server move or deployment

The crontab belongs to a user on a specific server. After migrations, rebuilt containers or a new release path, it is often missing or points to the old directory. Reinstall with bin/magento cron:install --force as the file system owner and confirm with crontab -l.

Indexes never catch up

If the backlog in indexer:status keeps growing, the index cron job cannot keep up or is not running. Common causes are a single long-running job blocking the group, large imports that write millions of changelog rows, and under-sized database servers. Look at which job is slow before adding hardware. Some large stores run the index group in a separate process so a slow default job cannot delay indexing.

Triggers missing after a database import

Update by Schedule depends on MySQL triggers. Restoring a dump without triggers, or copying production data into staging with tools that skip them, leaves changelogs empty and indexes silently stale. Switching the indexers to Update on Save and back to Update by Schedule recreates the triggers; then run a reindex.

Full reindex during trading hours

bin/magento indexer:reindex rebuilds whole indexes and can load the database heavily on large catalogs. Prefer letting the scheduled indexer process changes. When you need a full rebuild, run it off-peak and reindex only the indexers that need it.

Cron running on several servers

In a multi-node setup, every web node running the same crontab can execute jobs more than once or fight over locks. Run cron on one designated node, or on a separate worker, unless your hosting platform manages this for you.

Extension jobs slowing everything down

Third-party modules often add their own cron jobs. A job that exports a full catalog every minute can starve the rest. The cron_schedule query above shows which job codes run most often and fail most often.

Healthy cron and indexing are also a performance issue: stale price or stock indexes cause extra work at request time and confusing cache behavior. Our list of Magento speed optimization fixes covers the wider picture.

FAQ

How often should Magento cron run?

Every minute. Magento decides internally which jobs are due, so a less frequent crontab only delays everything.

Is it safe to truncate the cron_schedule table?

It holds schedule and history, not business data, and Magento rebuilds the schedule. Even so, prefer adjusting history lifetimes in the cron settings, and back up first if you clear it.

Should I use Update on Save for a small store?

It works, but Adobe recommends Update by Schedule for all indexers, and it avoids lock contention when several people edit products at once.

Cron and indexer monitoring is routine work that is easy to forget until something goes stale. Mistri includes these checks in Magento support and maintenance, and treats slow or backlogged indexing as part of performance optimization when it affects the storefront.

Sources

Adobe Experience League: Configure and run cron; Adobe Experience League: Manage the indexers; Adobe Experience League: Index Management; Adobe Developer: Indexing overview.