Stability & Scaling

Magento Cron Health as an Early Warning Signal

When Magento cron falls behind, indexing, email, and cleanup all degrade quietly. Read cron health from the cron_schedule table before customers notice.

Jason Schuman · March 18, 2026

Cron is Magento's quiet heartbeat

Magento uses cron, the system scheduler, for background work customers do not see directly. That work includes reindexing, sending email, cleaning expired quotes, generating catalog price rules, and flushing caches on schedule.

When cron stops working, the storefront may keep serving pages. Indexes become stale, emails stop sending, and cleanup jobs do not finish. The problem can stay hidden until a customer notices the result.

This article shows how to check cron health from one table, understand each status value, and use the cron_schedule table as an early warning.

Cron Health Early Indicator. Catch trouble before users do.

What Magento cron runs

Magento organizes scheduled work into groups, mainly default, index, and consumers. Each group contains jobs, and Magento records each job in the cron_schedule table.

One system crontab line normally starts the scheduler: * * * * * php bin/magento cron:run. Magento can install that line with bin/magento cron:install. If the line is missing or the process cannot run, scheduled work stops.

One query exposes cron health

You do not need a monitoring tool for the first check. Group the schedule table by status:

SELECT status, COUNT(*) FROM cron_schedule GROUP BY status;

On a healthy store, most rows are usually success. A smaller number of pending jobs are waiting for their scheduled run. A large group of any other status is a signal to investigate.

What each cron status means

The status column gives you the first clue about the scheduler. Each value points to a different type of problem:

  • A pile of missed jobs means cron is not running often enough, or not running at all, to keep up with the schedule.
  • Rows stuck in running that never resolve usually mean a job was killed during execution, often by a PHP memory limit or a deployment.
  • A growing backlog of pending means jobs are being scheduled faster than they finish.
  • Repeated error rows point at one specific job failing every run, which the job_code column names exactly.
A stuck running row that never flips to success or error is not a job still working. It is almost always a job that was killed and will never report back.

Find the job behind the failure

Once the status counts show a problem, run a second query to identify the job. Filter for missed, running, and error rows, then read the job_code:

SELECT job_code, status, scheduled_at, executed_at
FROM cron_schedule
WHERE status IN ('missed', 'running', 'error')
ORDER BY scheduled_at DESC
LIMIT 20;

If one job_code repeats across the failures, it identifies the feature to inspect. An index job points to reindexing. A consumers job points to message-queue work. A custom job_code points to the extension that registered it.

Table bloat is a cron symptom

The cron_schedule table should stay reasonably small because Magento removes old schedule history. When it holds hundreds of thousands of rows, the cleanup work is not completing correctly.

Table growth is often the first visible sign of a scheduler problem. The bloat is evidence that maintenance is failing. It is not the root cause, so inspect the cron jobs and status values that explain why cleanup stopped.

Cron must run every minute

The standard Magento cadence is once a minute. The crontab entry * * * * * provides that cadence. This does not mean every job runs every minute. Each job has its own schedule inside Magento.

The every-minute run gives Magento a chance to check which jobs are due and dispatch them. If the system crontab runs every five or ten minutes instead, jobs can pile up as missed because the scheduler is not checking often enough.

Four causes explain most cron failures

Most cron problems come from one of four conditions. Check them in this order:

  • Cron is not installed in the system crontab at all, so nothing runs.
  • Cron runs as the wrong system user and cannot write to the var/ or generated/ directories.
  • Jobs exceed the PHP CLI memory limit and are killed partway, leaving running rows behind.
  • Overlapping cron:run processes collide because a previous run never finished.

The status counts tell you which cause to check first. Confirm the system crontab, the user that runs it, PHP CLI memory limits, and overlapping processes.

Use cron as an early warning

Cron health can expose problems before they reach the storefront. Stale indexes, unsent order emails, and quote tables that never get cleaned can all result from failed scheduled work.

Checking the status counts takes about a minute. If background work is falling behind, you can find the problem before a customer reports its effect.

A scheduled query is enough for a basic alert. Count missed and error rows once a day, then alert when either count rises. This can detect a failing scheduler within hours instead of waiting for the next stale-index complaint.

No new tooling is required for this first check. The store already maintains the cron_schedule table.