Magento 2: Creating & Running Cron in Custom Module

This article shows how to create and run cronjob in a custom module in Magento 2. To know about general details about setting up and running cron on Magento 2, you may refer to this official documentation. This documentation will show you how you can create cron job on web server as well.

Here, we will focus on creating / setting up / running cron for a custom Magento 2 module.

Let us suppose, we are developing a custom module named YourNamespace_YourModule (app/code/YourNamespace/YourModule). To define the cron settings for your custom module, you need to write the following code in app/code/YourNamespace/YourModule/etc/crontab.xml.

app/code/YourNamespace/YourModule/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="your_cron_name" instance="YourNamespace\YourModule\Cron\Test" method="execute">
            <schedule>*/30 * * * *</schedule>--> <!-- run 30th minutes -->
        </job>
    </group>
</config>

As you can see from above code, we have defined to run the execute method of class Test (app/code/YourNamespace/YourModule/Cron/Test.php) every hour when the cronjob is run in the server. The group id is set as “default”. You can give it your custom name as well.

Here’s the basic content:


<config>
    <group id="<group_name>">
        <job name="<job_name>" instance="<classpath>" method="<method>">
            <schedule><time></schedule>
        </job>
    </group>
</config>

Here is our class file. We will just log some text to test if the cron is working properly. The log text is saved in var/log/debug.log.

app/code/YourNamespace/YourModule/Cron/Test.php


<?php
namespace YourNamespace\YourModule\Cron;

class Test {
 
    protected $_logger;
 
    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->_logger = $logger;
    }
    
    /**
     * Method executed when cron runs in server
     */
    public function execute() {
        $this->_logger->debug('Running Cron from Test class');
        return $this;
    }
}

You can manually run cron from terminal/command line with the following command:

Run all cron jobs


sudo php bin/magento cron:run

If it doesn’t work (doesn’t create any entries in cron_schedule table) then try flushing cache first:


sudo php bin/magento cache:flush

Run cron jobs of a particular group only


sudo php bin/magento cron:run --group="<cron group name>" 

There are two group names/ids by default in Magento. They are default and index. If you want to add a new group id for your custom module then you have to create a new file app/code/YourCompany/YourModule/etc/cron_groups.xml:


<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/cron_groups.xsd">
    <group id="your_group_name">
        <schedule_generate_every>15</schedule_generate_every> <!-- Write schedules to cron_schedule table every X minutes -->
        <schedule_ahead_for>20</schedule_ahead_for> <!-- Write schedules to cron_schedule table X minutes in advance -->
        <schedule_lifetime>15</schedule_lifetime> <!-- X minutes lifetime of schedule. Job failed if not finished in X minutes. -->
        <history_cleanup_every>10</history_cleanup_every> <!-- Clean cron history every X minutes -->
        <history_success_lifetime>60</history_success_lifetime> <!-- Clean success jobs history every X minutes -->
        <history_failure_lifetime>600</history_failure_lifetime> <!-- Clean failed jobs history every X minutes -->
        <use_separate_process>0</use_separate_process> <!-- If 1, all cron jobs will run in parallel. If 0, all cron jobs run one after another. -->
    </group>
</config>

You can check your new cron group in admin panel at:
Stores -> Configuration -> Advanced -> System -> Cron (Scheduled Tasks)

If your group id is named “your_group_name” then to run cron jobs for that group only, you will have to run the following command:


sudo php bin/magento cron:run --group="your_group_name"

After you run the above command, you can check your database table named cron_schedule. This table has fields like job_code, status, messages, created_at, scheduled_at, executed_at, etc. So, by looking into this table, you can know about the status of all the cron jobs.

Hope this helps.
Thanks.