HowTo: Create a Cron Job in Magento 2
On this page
A while ago I needed to run a task automatically every night to clean up some old rows from a custom table. The obvious tool for the job is a cron job, but if you come from Magento 1 the syntax changed a bit, so let me show you how I set it up.
app/code/Vendor/Module. If you need to know how to create a custom module, look at How to create a custom module for Magento 2.The crontab.xml
Magento reads the jobs of every module from its etc/crontab.xml file, so that is the first thing we need to create.
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/etc/crontab.xml -->
<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="vendor_module_cleanup" instance="Vendor\Module\Cron\Cleanup" method="execute">
<schedule>0 2 * * *</schedule>
</job>
</group>
</config>There are a couple of things worth explaining here:
- The
instanceandmethodtell Magento which class and method to run, in this caseVendor\Module\Cron\Cleanup::execute(). - The
<schedule>uses the standard cron expression.0 2 * * *means every day at 2:00 AM. - The
group idlets you run your jobs in a separate group if you need to, but for most cases thedefaultgroup is fine.
<schedule> with <config_path>vendor_module/cron/schedule</config_path> and expose that value in system.xml.The Cron Class
Now we create the class we referenced in the instance attribute. Keep it thin, the cron is just an entry point,
the real work should live in a service.
<?php
/** app/code/Vendor/Module/Cron/Cleanup.php */
namespace Vendor\Module\Cron;
use Psr\Log\LoggerInterface;
class Cleanup
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* @return $this
*/
public function execute()
{
$this->logger->info('Vendor\Module cleanup cron started');
// Your logic here, e.g. delete old rows, send a report, warm a cache...
return $this;
}
}Testing it
You don’t have to wait until 2 AM to know if it works. You can trigger the group manually:
bin/magento cron:run --group=defaultThen check var/log/system.log (or your custom logger) and you should see the message we logged.
* * * * * php /path/to/magento/bin/magento cron:run. Running bin/magento cron:install sets this up for you.Hope this helps.
If you have any question or know a better way to achieve this, feel free to share in the comments below.
Related links: