Understanding Magento 2's Cron Functionality

Understanding Magento 2's Cron Functionality

Learn how scheduled tasks (cron jobs) are managed via crontab.xml files within Magento 2's cron architecture.

If you've worked with Magento 2, you probably understand that certain tasks are scheduled and executed routinely. These scheduled tasks are part of Magento's cron functionality.

How scheduled tasks work in Magento may not be as simple as you think. It's important to first understand how cron jobs work in M2 before being able to set up and configure one. We’ll go over what a cron even is and all of the terms and pieces, and how they relate to and work with Magento’s framework.

What is the difference between a cron, crontab, and cron job?

Before we get started, it's easy to mistake the main cron-based terminology and to know how the terms should be used and the difference between them.

A cron is an application daemon service that runs on the server and executes scheduled tasks. You can think of this as a background software app that runs and executes jobs from a crontab file.

A crontab is a configuration file, and its name is short for cron table. A crontab file contains a list of jobs that run on a defined schedule at specific times. This schedule is defined in a cron expression format (e.g., * * * * *), and you can learn more about cron expressions from cron guru.

A cron job is an individual scheduled task listed in a crontab file. There can be one or many cron jobs defined within a single crontab file.

How does Cron work with Magento?

In normal PHP applications, you would typically define many cron jobs within a single crontab file. Each job then executes on the schedule specified within the cron expression.

For example, here is a crontab file that contains two cron jobs:

/etc/crontab
# Run a PHP script every day at 3:00 AM
0 3 * * * /usr/bin/php /var/www/html/daily_backup.php
 
# Run another PHP script every 30 minutes
*/30 * * * * /usr/bin/php /var/www/html/check_notifications.php

Things work a bit differently in Magento. Defining many cron jobs for multiple modules within a crontab file would be extremely difficult to manage and maintain, as this file is managed outside the scope of a Magento project. This means that it isn't managed within a version control system and is hard to administer between multiple environments.

So alternatively, for Magento instances, a single cron job is defined which is the same for all environments and reads as a variation of the following:

/etc/crontab
* * * * * /usr/local/bin/php /var/www/html/bin/magento cron:run 2>&1 | grep -v "Ran jobs by schedule" >> /var/www/html/var/log/magento.cron.log

The command above executes the bin/magento cron:run script every minute, as defined with the * * * * * cron expression. Everything that follows that command essentially pipes the output of that command's execution to the /var/log/magento.cron.log file.

This means that the management and execution of scheduled tasks in Magento is completely managed by Magento's cron:run command. Each minute, the bin/magento cron:run executes, which in turn calls the native Magento PHP script.

Defining cron jobs in Magento

With this single cron job architecture in place, Magento implements its own cron system internally. This allows custom modules to tap into Magento's scheduled task functionality.

Cron jobs are an essential part of Magento's framework. They keep things running smoothly and handle everything from indexing products to sending out customer emails. You can also tap into Magento's internal cron functionality to define your own custom scheduled tasks.

Just like we can define a crontab file on a Unix server, we can define our own crontab file within Magento, but in standard Magento fashion… it's gotta be an XML file.

What is the purpose of crontab.xml?

The purpose of the crontab.xml file is to specify the following details for each cron job:

  • Job Name: An identifier for the cron job, which must be unique across all other cron jobs in Magento.
  • Schedule: The frequency at which the cron job should run, which is defined in cron expression syntax.
  • Run Model: The class and method that should be executed when the cron job runs.

This file is placed within the etc/crontab.xml file of any Magento module and resembles something similar to the following:

etc/crontab.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="default">
        <job name="daily_backup" instance="Vendor\Module\Cron\DailyBackup" method="execute">
            <schedule>0 3 * * *</schedule>
        </job>
        <job name="check_notifications" instance="Vendor\Module\Cron\CheckNotifications" method="execute">
            <schedule>*/30 * * * *</schedule>
        </job>
    </group>
</config>

You'll notice that the daily_backup and check_notifications tasks are the same cron jobs as the previous examples we looked at, but this time in Magento's crontab XML format. We are simply defining the class instance responsible for this cron job and the related method to execute.

Cron groups

Looking at the example above and just about any other crontab.xml file in Magento, you'll notice that the group ID is always default. This is the default group used to organize cron jobs.

That said, you can define your own custom group name to better organize your custom cron job tasks. For example, setting <group id="foo"> places your cron jobs into a new foo group. While you'll usually use the default group, using a custom group can be advantageous, especially during development, as Magento also allows you to execute cron jobs per group with:

bin/magento cron:run --group=foo

This line will only execute cron jobs associated with the foo group.

This approach lets you focus on your custom cron jobs during development without triggering all the other cron jobs in Magento. It can be a real time-saver, especially when you are knee-deep in development and debugging your code.

crontab.xml works with cron_schedule

Though the main cron:run command is executed every minute, cron expressions defined within crontab.xml files take over. These crontab files work in tandem with the cron_schedule MySQL database table to determine when the cron job was last executed and when to execute it next.

The cron_schedule Database Table

When a cron job is scheduled to run based on the configuration defined in the related crontab.xml file, Magento creates a corresponding entry in the cron_schedule database table within MySQL. This table keeps track of the execution status and other details about each cron job instance.

The cron_schedule table contains the following columns:

  • job_code: The unique identifier of the cron job instance, as defined in the crontab.xml file's job.name property.
  • status: The current status of the cron job instance (e.g., pending, running, success, missed, error).
  • messages: Information specific to the cron job instance.
  • created_at: The timestamp when the cron job instance was created.
  • scheduled_at: The timestamp when the cron job instance is scheduled to run.
  • executed_at: The timestamp when the cron job instance actually started running.
  • finished_at: The timestamp when the cron job instance finished running.
  • group: The group defined for the cron job instance; typically default.
  • hostname: The name of the server that executed the cron job instance, which is useful if you are running multiple Magento instances to process cron jobs.
  • duration: The number of seconds the cron job instance took to execute.
  • pid: The process ID of the related execution tick of bin/magento cron:run.
  • kill_request: The timestamp when the cron job instance process was killed.

When the Magento cron process runs, it looks for pending jobs in the cron_schedule table and executes them based on their scheduled time.

Important cron_schedule table info

There are a few important things to keep in mind regarding the cron_schedule table:

  1. Cron Job Statuses: Pay attention to the status column in the cron_schedule table. If you notice a high number of "missed" or "error" statuses, it could indicate issues with your cron configuration or the specific cron job implementation.
  2. Cron Job Performance: Monitor the executed_at and finished_at timestamps to ensure that cron jobs are running in a timely manner. If you observe significant delays or long execution times, this may suggest performance bottlenecks or resource constraints.
  3. Table Size: The cron_schedule table can grow quite large over time, especially if you have many cron jobs configured. Regularly clean up old entries from the table to prevent excessive growth and keep things running optimally.
  4. Cron Configuration: Ensure that your server's cron is properly configured to run the Magento cron process. Without a correctly set up cron, none of the jobs defined in crontab.xml files will be executed.

Recap

To wrap things up, Magento 2's cron functionality is a powerful tool for managing scheduled tasks within the platform. By understanding the relationship between the crontab.xml configuration files and the cron_schedule database table, you can more effectively create, monitor, and troubleshoot custom cron jobs as a Magento developer.

Here are a few takeaways to remember:

  • Do not define cron jobs within a system cron, but rather in the appropriate crontab.xml file using the appropriate syntax that Magento expects you to use.
  • Utilize cron groups to organize and selectively run specific sets of cron jobs during development.
  • Monitor the cron_schedule table for any anomalies or performance issues.
  • Regularly clean up old entries in the cron_schedule table to maintain optimal performance.
  • Ensure that your server's cron is properly configured to execute Magento's cron process.

By following these guidelines and best practices, you can harness the full potential of Magento 2's cron functionality to automate tasks, optimize performance, and keep your store running smoothly.

Next Steps

  1. Learn how to add a column to the sales order database table (Article)
  2. Start learning M2 fundamentals with Jumpstart Course (Free, 13,000+ Students)
  3. Kickstart learning Magento to truly understand the framework (700+ Students)