Adobe's official Configuration Guide does not hedge: all asynchronous operations in Commerce are performed via the Linux cron command, and failure to configure it correctly will prevent Commerce from functioning as expected. For stores processing thousands of orders a day, that lands hard. Stuck indexers, missed transactional emails, and runaway report-generation jobs are the typical results. They almost always surface during peak traffic, because no one noticed cron degrading in the background.
April 2025 raised the bar on what a correct setup looks like. Adobe Commerce 2.4.8 changed the default indexer mode to Update by Schedule for all indexers, including the Customer Grid indexer, which previously supported only Update on Save. It also added automatic cleanup of orphaned entries in the cron_schedule table, closing a long-standing GitHub issue where disabled extensions left rows accumulating indefinitely. Stores not yet on 2.4.8 must handle both problems manually.
What follows is what a technical team actually needs to monitor Magento cron on a high-traffic production store: how cron groups work, which log files and database queries catch problems before they escalate, how to use Adobe's Observation for Adobe Commerce tool, and the specific configuration values that prevent the most common failure modes. Every recommendation links to Adobe's official documentation.
How Magento Cron Actually Works?
Magento runs two cron processes, not one. Knowing the difference is what makes debugging faster. The first, bin/magento cron:run, is the scheduler. It reads the cron_schedule table for pending jobs and dispatches them. The second process executes those jobs, either inline or as a separate PHP fork, depending on the use_separate_process setting for each cron group. Adobe's documentation is clear: you must run cron twice. The first pass discovers tasks, the second runs them. Missing this is one reason custom cron jobs appear scheduled but never fire.
Magento organizes its scheduled jobs into three primary cron groups.
|
Cron Group |
Primary Responsibilities |
Key Config Note |
|
default |
Newsletters, currency rates, product alerts, sitemaps, cache cleanup, session cleanup, sales reports |
Runs every minute; moderate database impact |
|
index |
Product, category, and price reindexing via MView changelog tables |
Lower concurrent limits due to database intensity; runs separately |
|
consumers |
Message queue consumers for async order processing and RabbitMQ integration |
Set consumers_wait_for_messages = 0 in env.php to prevent indefinite blocking |
The index group is where resource problems start. When Update on Save mode is active, every admin product edit triggers immediate reindexing. On large catalogs under load, this causes significant delays and data unavailability, according to Adobe's Performance Best Practices guide. Update by Schedule batches those changes through a cron job instead. That shift alone removes a large category of peak-hour performance incidents.
Step 1. Verify the Crontab is Configured Correctly
If transactional emails are delayed, reindexing is running late, or the store just feels sluggish with no obvious cause, check whether cron is installed at all. Adobe's documentation is explicit: Commerce services must be installed in crontab or core components and some third-party extensions will not function as expected.
Check the installed crontab as the file system owner:
| crontab -l |
The output should contain a block bounded by #~ MAGENTO START and #~ MAGENTO END comments. A correct single-server setup looks like this:
| * * * * * /usr/bin/php /var/www/html/bin/magento cron:run 2>&1 | grep -v "Ran jobs by schedule" >> /var/www/html/bin/magento/var/log/magento.cron.log |
If that block is absent, run bin/magento cron:install as the file system owner. On Adobe Commerce Cloud, cron lives in the .magento.app.yaml file under the crons property. Adobe's Cloud documentation recommendstesting cron updates in the remote integration environment before pushing to staging or production.
Multi-node environments: Adobe's configuration guide specifies that the crontab should run only on one node. Running it across multiple web nodes results in duplicate job executions and race conditions in the cron_schedule table.
Step 2: Configure Cron Group Settings in the Admin
Go to Stores > Settings > Configuration > Advanced > System > Cron. Each group exposes six fields. Getting them wrong on a high-traffic store either bloats the cron_schedule table or marks jobs as missed before they get a chance to run.
|
Admin Field |
Default Value |
Recommendation for High-Traffic Stores |
|
Generate Schedules Every |
1 min |
Keep at 1 min. Increasing it delays new jobs from entering the queue. |
|
Schedule Ahead For |
4 min |
Raise to 10-20 min. Pre-queued jobs survive brief cron delays during load spikes. |
|
Missed if Not Run Within |
2 min |
Raise to 5-10 min on stores with variable server startup times to cut false Missed statuses. |
|
History Cleanup Every |
10 min |
Keep at 10 min. Infrequent cleanup lets the cron_schedule table bloat. |
|
Success History Lifetime |
60 min |
Fine for most stores. Drop to 30 min on very high-volume stores to keep the table lean. |
|
Failure History Lifetime |
600 min |
Keep at 600 min (10 hours). Do not lower this during active debugging. |
The cron_schedule table writes a record at the start and finish of every cron job. Adobe's Observation for Adobe Commerce tool tracks updates to this table as a proxy for cron health. Long-duration updates signal cron stackup or a scheduling problem. Once the table grows past a few thousand rows and cleanup is not running often enough, query performance degrades, and cron itself slows down.
Step 3: Switch All Indexers to Update by Schedule
Adobe's Performance Best Practices guide recommends Updating on Schedule explicitly, because Updating on Save can cause significant delays and data unavailability during high loads. This one change reduces peak-hour contention more than almost anything else.
Check current indexer modes:
| bin/magento indexer:show-mode |
Set all indexers to Update by Schedule:
| bin/magento indexer:set-mode schedule |
Adobe's 2.4.8 release notes made this the platform default for new installations and upgrades. Stores on earlier versions must make the switch manually.
Before switching modes on a live store: put the website in maintenance mode and disable cron jobs first. Adobe's indexer documentation is specific about this because switching modes while cron is active can cause database lock conflicts.
For stores where saving a configuration with many store-level entries causes timeouts, the Async Config module offloads those saves to a cron-driven message queue. Enable it via CLI:
| bin/magento setup:config:set --config-async 1 |
Then start the config queue consumer:
| bin/magento queue:consumers:start saveConfigProcessor --max-messages=1 |
Adobe's Configuration Best Practices covers this in detail.
Step 4: Monitor the cron_schedule Table Directly
The cron_schedule table is the ground truth for cron health. It records every job's status, scheduled time, execution time, and finish time. Adobe's CLI documentation confirms all cron data is written here, including job code, status, created date, scheduled date, executed date, and finished date.
Add these queries to your regular monitoring rotation.
Detect Jobs Stuck in Running Status
|
sql SELECT job_code, scheduled_at, executed_at, TIMESTAMPDIFF(MINUTE, executed_at, NOW()) AS running_minutes FROM cron_schedule WHERE status = 'running' AND executed_at < NOW() - INTERVAL 30 MINUTE ORDER BY running_minutes DESC; A job stuck in running for more than 30 minutes has almost certainly hung. On Adobe Commerce Cloud, use ece-tools cron:unlock to release it: ./vendor/bin/ece-tools cron:unlock --job-code=<job_code> |
Measure Failure Rate Per Job in the Last 24 Hours
|
sql SELECT job_code, SUM(status = 'success') AS success, SUM(status = 'failed') AS failed, SUM(status = 'missed') AS missed FROM cron_schedule WHERE scheduled_at > NOW() - INTERVAL 24 HOUR GROUP BY job_code HAVING failed > 0 OR missed > 0 ORDER BY failed DESC; |
A missed status means Magento scheduled the job, but cron did not execute it within the Missed if Not Run Within window. A burst of missed jobs at a specific time usually points to server resource exhaustion or a cron process that did not start. A failed status means the job started and threw an exception. Failed jobs with ERROR status are always logged as CRITICAL in exception.log.
Step 5: Check the Log Files
Since Magento 2.4.0, cron information is logged in its own file rather than in the general system log. Default location: <install_directory>/var/log/cron.log. Three additional files matter when something goes wrong:
- cron.log: Primary cron execution log. All jobs, execution times, and normal output.
- support_report.log: Failed jobs with ERROR and MISSED statuses are written here.
- exception.log: Jobs with ERROR status appear here as CRITICAL entries.
- debug.log: MISSED statuses appear here as INFO entries, but only in developer mode.
On Cloud infrastructure, use ece-tools cron:disable before any maintenance window that involves reindexing or cache clearing. It prevents cron from firing conflicting jobs mid-task. Re-enable with ece-tools cron:enable when you are done.
Step 6: Use Observation for Adobe Commerce to Monitor Cron at Scale
Observation for Adobe Commerce is Adobe's dedicated monitoring tool for Commerce sites. It is a New Relic nerdlet (a custom application built on New Relic's programmability interfaces) that pulls log data from multiple sources into a single dashboard. Adobe's backend performance playbook explicitly recommends it for tracking cron-related performance indicators.
Two cron-specific data points in the tool are worth watching closely:
- cron_schedule table update duration: The MySQL tab tracks the maximum duration of database updates to the cron_schedule table for any selected time window. Sustained high durations indicate cron stackup.
- Lock detection: The MySQL tab also surfaces database locks per cron job code, including common culprits like magento_newrelicreporting_cron and catalog_product_attribute_value_synchronize.
Observation for Adobe Commerce is available for both Cloud and on-premises deployments. Access it from the New Relic home page under the Apps menu. During a performance incident, the Summary tab's cron_schedule table updates frame is the fastest confirmation of whether cron is processing at the expected rate.
Step 7: Separate Heavy Cron Jobs from Customer-Facing Traffic
Adobe's Performance Best Practices guide states it directly: all asynchronous operations run via cron. Poorly scheduled jobs compete for the same CPU and database connections as live customer requests. Three patterns cause most of the contention on high-traffic stores.
Report generation during peak hours.
Jobs like aggregate_sales_report_bestsellers_data do heavy full-table scans on sales_order and sales_order_item. Adobe released Quality Patch ACSD-51857 (fixed in 2.4.7) specifically because this job was degrading performance on large tables. Schedule report jobs for off-peak hours.
Flat catalog indexers.
Adobe's troubleshooting documentation states outright that flat catalog indexers are no longer a best practice and are not recommended. They can cause the cron process to get stuck, time out, or miss other important jobs. Disable them under Stores > Configuration > Catalog > Catalog > Storefront.
Message queue consumers are running indefinitely.
Queue consumers can wait indefinitely for new messages by default, blocking cron slots. Set 'consumers_wait_for_messages' => 0 in app/etc/env.php so consumers terminate cleanly after processing their batch. Adobe's message queue management documentation covers this in full.
For on-premises stores with very high order volumes, consider moving queue consumers off cron entirely and onto a dedicated process manager like Supervisor, with RabbitMQ as the broker. It removes the single biggest source of blocking on large Commerce installations.
Step 8: Handle the cron_schedule Table Bloat Problem
In stores running for more than a year without careful cleanup settings, the cron_schedule table routinely accumulates tens of thousands of rows. Before 2.4.8, rows from removed extensions stayed in the table indefinitely because the cleanup routine only processes jobs that still exist in the active codebase. A bloated table slows down cron:run on every cycle, since it has to query the table to find pending jobs each minute.
Manual cleanup for pre-2.4.8 stores:
|
sql DELETE FROM cron_schedule WHERE status = 'success' AND finished_at < NOW() - INTERVAL 1 HOUR; DELETE FROM cron_schedule WHERE status IN ('failed','missed') AND finished_at < NOW() - INTERVAL 24 HOUR; DELETE FROM cron_schedule WHERE job_code NOT IN (SELECT DISTINCT job_code FROM cron_schedule WHERE status = 'running'); |
Run OPTIMIZE TABLE cron_schedule after a large deletion to reclaim disk space. If you have not upgraded to 2.4.8 yet, put this on a weekly maintenance schedule.
Starting with 2.4.8, automatic cleanup handles orphaned entries. Still verify that History Cleanup Every is set to 10 minutes in the Admin. The automation only helps if it runs frequently enough.
Monitoring Commands Quick Reference
|
Task |
Command or Location |
|
View installed crontab |
crontab -l |
|
Run cron manually |
bin/magento cron:run |
|
Run index group only |
bin/magento cron:run --group index |
|
Check indexer modes |
bin/magento indexer:show-mode |
|
Set all indexers to schedule |
bin/magento indexer:set-mode schedule |
|
Cron log file |
<install_dir>/var/log/cron.log |
|
Cloud: disable cron |
./vendor/bin/ece-tools cron:disable |
|
Cloud: unlock stuck job |
./vendor/bin/ece-tools cron:unlock --job-code=<code> |
|
Install crontab |
bin/magento cron:install [--force] |
Frequently Asked Questions
Here are the common questions and it's answer you might have.
1. How Often Should Magento Cron Run in Production?
Adobe's official documentation recommends every minute (* * * * *). That is the default crontab setting and it holds for most production stores. Dropping to every 5 minutes reduces server load slightly but poses real risks: delayed transactional emails, missed pending payment lifetime checks, and other short-window jobs that depend on that frequency.
2. What Does a Missed Cron Job Status Mean?
Magento scheduled the job, but cron did not execute it within the Missed if Not Run Within window, which defaults to 2 minutes. On high-traffic stores the usual cause is one of three things: cron:run itself taking longer than a minute because of server load, a long-running job blocking the process queue, or the crontab not being installed at all. If missed statuses appear in bursts, raise the threshold to 5-10 minutes before assuming the jobs themselves are broken.
3. Can I Run Cron Jobs on a Separate Server?
Yes, and for high-traffic stores it is worth doing. A dedicated cron server keeps background job execution off the same hardware handling customer HTTP requests, freeing CPU and database connections for frontend traffic. The cron server still connects to the shared database, so database-intensive jobs like reindexing are isolated from page load performance.
4. What Changed About Magento Cron in Version 2.4.8?
Adobe Commerce 2.4.8 (released April 8, 2025) shipped four cron-related changes: automatic cleanup of the cron_schedule table for jobs from removed extensions; Update by Schedule as the default mode for all indexers, including the Customer Grid indexer for the first time; removal of unused changelog tables when switching indexer modes; and improved bulk tier price updates via the REST API that reduce the cron-triggered reindex load.
5. How Do I Monitor Cron on Adobe Commerce Cloud?
Adobe provides two tools. Observation for Adobe Commerce is a New Relic nerdlet available to all Commerce Cloud customers. It shows cron_schedule table update durations and database lock data on a single dashboard. New Relic Managed Alerts for Adobe Commerce add pre-built alerting policies with step-by-step troubleshooting guidance. Access both from the New Relic account linked to your Commerce Cloud project.
What to Do Based on Your Situation?
On Adobe Commerce 2.4.8 or later, the cron defaults are correct out of the box. Set up Observation for Adobe Commerce, run the failure-rate SQL query weekly, and confirm History Cleanup Every is at 10 minutes.
On 2.4.6 or 2.4.7, add manual cron_schedule cleanup to your maintenance schedule and switch all indexers to Update by Schedule now, not eventually.
Seeing Missed jobs in bursts? Raise the Missed if Not Run Within threshold before investigating the jobs themselves. Seeing jobs stuck in running? Start with flat catalog indexers, indefinite queue consumers, and third-party jobs with no execution timeout. The cron_schedule table has over 50,000 rows? Run the deletion queries and optimize the table first. Table bloat is often the root cause of cron slowdowns, not a byproduct of them.
Also read: Magento 2 System Health Monitoring: The Ultimate Guide for Store Owners & Developers



