Insights

    Magento 2 Cron Not Running? How to Check and Fix It

    By Simon Bumford, Founder of EveryHostLast updated 8 min read

    If Magento 2 cron is not running, check three things in order: that Magento's crontab exists for the user that owns the Magento files, that recent jobs are appearing in the cron_schedule table, and what the cron log says. Most cron problems come from a missing or wrong crontab, a job that died part way through, or a command-line PHP that doesn't suit the store. This guide covers each check, how to run cron by hand, and what missed, failed and stuck jobs mean.

    What cron does in Magento

    Cron runs Magento's background work; when it stops, the store keeps taking orders but slowly drifts out of date.

    Adobe's own partial list of what cron runs includes catalog price rules, newsletters, Google sitemaps, customer alerts such as price changes and back-in-stock notices, reindexing, automatic currency rate updates, and all Magento emails, including order confirmations. Cron also starts Magento's message queue consumers through the consumers_runner job, which bulk admin actions and some asynchronous operations depend on.

    Jobs are organised in cron groups. Magento Open Source has three:

    • default: most cron jobs.
    • index: the jobs that refresh the indexers.
    • consumers: the message queue consumers.

    Adobe Commerce adds a staging and a catalog_event group.

    How to check Magento cron status

    1. Is Magento's crontab installed?

    Log in as the user that owns the Magento files, not root, and list the crontab:

    crontab -l

    You should see Magento's block, which bin/magento cron:install writes between two marker lines. The PHP path and install path will be your own:

    #~ MAGENTO START <hash>
    * * * * * /usr/bin/php /var/www/html/magento2/bin/magento cron:run 2>&1 | grep -v "Ran jobs by schedule" >> /var/www/html/magento2/var/log/magento.cron.log
    #~ MAGENTO END <hash>

    If it's missing, install it from the Magento root as the same user:

    bin/magento cron:install

    bin/magento cron:install --force rewrites an existing Magento block, for example after you change the PHP path. Adobe notes it has no effect on cron jobs outside Magento's markers. bin/magento cron:remove takes Magento's entries out again; Adobe says to use it only before uninstalling.

    2. Are jobs being scheduled and run?

    All cron activity is written to the cron_schedule table. Look at the most recent jobs:

    SELECT job_code, status, scheduled_at, executed_at, finished_at
    FROM cron_schedule
    ORDER BY scheduled_at DESC
    LIMIT 20;

    On a healthy store you'll see recent pending jobs waiting their turn and recent success rows. If the newest rows are hours old, cron isn't firing. Adobe's own check for the job that keeps scheduled indexers up to date is:

    SELECT * FROM cron_schedule WHERE job_code = "indexer_update_all_views" AND status <> "success" AND status <> "pending";

    3. What does the cron log say?

    Adobe gives var/log/cron.log as the default cron log. The crontab that cron:install writes also sends its output to var/log/magento.cron.log, so check both. Failed and missed jobs are also logged elsewhere: Adobe says they go to var/log/support_report.log, failed jobs appear as critical errors in var/log/exception.log, and missed jobs appear in var/log/debug.log in developer mode.

    How to run Magento cron manually

    To force cron to run, run bin/magento cron:run from the Magento root, as the file owner, at least twice.

    bin/magento cron:run
    bin/magento cron:run

    Adobe explains why twice: the first run discovers the tasks that are due, and the second run carries them out. To run one group only, name it:

    bin/magento cron:run --group=index

    Leaving out --group runs every group, and --exclude-group leaves one out. Running cron by hand is a test, not a fix: if jobs only run when you start them, the crontab is the problem.

    Missed, failed and stuck cron jobs

    A missed job never started in time, a failed job started and threw an error, and a stuck job started and never finished.

    Missed jobs

    Adobe: "If the cron job is not run at its scheduled time and the specified time elapses, it cannot be run and its status is set to Missed." That usually means cron isn't firing every minute, or another job is holding up the run. The timings are set per group under Stores > Settings > Configuration > Advanced > System > Cron (Scheduled Tasks):

    SettingWhat it controls
    Generate Schedules EveryHow often new schedule rows are created, in minutes
    Schedule Ahead forHow far ahead jobs are scheduled
    Missed if not Run WithinHow late a job can start before it is marked missed
    History Cleanup EveryHow often old rows are removed from cron_schedule
    Success History LifetimeHow long successful rows are kept
    Failure History LifetimeHow long failed rows are kept
    Use Separate ProcessWhether the group runs in its own system process

    The admin page shows the default and index groups; the consumers group's settings are covered in Adobe's message queue documentation.

    Failed jobs

    A job with an error status ran and threw an exception. The error is in var/log/exception.log and var/log/support_report.log. Fix the cause, often an extension's cron job, and the next scheduled run picks it up.

    Jobs stuck on running

    A job stays on running if its process died part way through, for example after hitting PHP's memory limit, a database timeout or a server restart. Find them with:

    SELECT * FROM cron_schedule WHERE status = 'running';

    Adobe's knowledge base article on this is written for Adobe Commerce on Cloud, which has its own unlock tool. On a self-managed server, Adobe publishes no equivalent, so this is our advice: check with ps aux that no PHP process is still running the job, take a database backup, then remove the stale row or mark it as an error so the next run can schedule the job again. Then find out why it died, or it will happen again.

    Common causes of Magento cron not running

    • The crontab belongs to the wrong user. Adobe says Magento's CLI commands, cron included, must run as the file system owner. A crontab installed under root can create files the web server can't use.
    • The crontab was lost. Crontabs aren't part of the Magento files, so they are easy to miss when a store moves server or a server is rebuilt. Run bin/magento cron:install after any move.
    • Command-line PHP doesn't suit the store. Cron uses the PHP path in the crontab, which can be a different PHP version or php.ini from the one the website uses. Adobe says to apply the same PHP settings to both the command line and the web server. Check with php -v and the path in crontab -l.
    • Jobs dying part way through. A low memory_limit or a database timeout leaves jobs stuck on running and later jobs missed.
    • Message queue consumers switched off. If cron_consumers_runner has cron_run set to false in app/etc/env.php, cron won't start the consumers. bin/magento queue:consumers:list shows which consumers exist.
    • Indexers waiting on cron. With indexers on Update by Schedule, nothing reindexes until cron runs. See our guide to Magento 2 reindex and indexers.

    Symptom, cause and fix

    SymptomLikely causeWhere to checkFix
    No new rows in cron_scheduleCrontab missingcrontab -l as the file ownerbin/magento cron:install
    Prices, stock or new products not updatingCron not running the index groupcron_schedule, indexer_update_all_viewsFix cron, then bin/magento cron:run --group=index
    Order emails not sendingCron not runningcron_schedule, var/log/cron.logFix cron; check the email queue
    Many missed jobsCron not firing every minute, or a slow job blockingCron settings, var/log/support_report.logConfirm the crontab runs every minute; find the slow job
    Jobs with an error statusAn exception in a cron jobvar/log/exception.logFix the job, often an extension
    Jobs stuck on running for hoursA job's process diedcron_schedule, ps auxClear the stale row once no process is running it; find the cause
    Bulk actions never finishConsumers not runningapp/etc/env.php, bin/magento queue:consumers:listRe-enable cron_run for consumers
    Cron runs by hand but not on its ownCrontab under the wrong user or PHP pathcrontab -l, php -vReinstall the crontab as the file owner with the right PHP

    Cron on EveryHost servers

    On EveryHost servers, we set up Magento's cron as part of the server, for the right user and PHP version, matched to your Magento version. Our Managed and Fully Managed plans also watch the Magento cron heartbeat, indexers and message queues, and an engineer investigates every alert. If cron stops on a store we host, raise a ticket: every plan includes 24/7 UK support by ticket through our support portal. For how cron fits into a slow store, see Why is Magento slow?.

    Frequently asked questions

    Run crontab -l as the user that owns the Magento files and check that Magento's block is there. Then look at the cron_schedule table: recent success and pending rows mean cron is running, while rows that stop hours ago mean it isn't. The cron log is var/log/cron.log.

    Run bin/magento cron:run from the Magento root as the file owner, twice: the first run schedules the jobs and the second runs them. Add --group=index to run only the indexing jobs. If jobs only run when you do this by hand, reinstall the crontab with bin/magento cron:install.

    The job didn't start within the "Missed if not Run Within" time for its cron group, so Magento marked it missed rather than running it late. It usually means cron isn't firing every minute or another job is holding up the run.

    Adobe gives var/log/cron.log as the default cron log. The crontab that bin/magento cron:install writes also sends output to var/log/magento.cron.log. Failed and missed jobs are also recorded in var/log/support_report.log, with errors in var/log/exception.log.

    A job stays on running when its process dies part way through, for example after running out of memory, a database timeout or a server restart. Check that no process is still running it, back up the database, then clear the stale row so the job can be scheduled again, and fix the cause.

    Want cron looked after for you?

    On EveryHost servers cron is set up for your store, and our Managed and Fully Managed plans watch it for you.