Cron Functionality
Understanding how to configure and run scheduled background tasks in Magento 2.
Cron System Overview
What is Cron?
Understanding Cron Systems
System Cron (UNIX/Linux/MacOS)
- Operating system feature
- Runs tasks on schedule
- Time-based job scheduler
- Configured via crontab
Example: Run a script every 5 minutes
*/5 * * * * /path/to/script.sh
Magento Cron
- Built on top of system cron
- Executes
pub/cron.php - Manages internal job scheduling
- Uses
cron_scheduletable
Purpose: Background tasks without HTTP requests
How Magento Cron Works
The Cron Workflow
Step-by-Step Process:
- System Cron Triggers - OS cron runs
pub/cron.php(orbin/magento cron:run) - Magento Pulls Jobs - Queries
cron_scheduletable for jobs due to run - Executes PHP Classes - Runs the
execute()method of each job - Updates Status - Marks jobs as success, error, or missed in database
- Once per minute:
* * * * * - Once per 5 minutes:
*/5 * * * * - Once per 15 minutes:
*/15 * * * *
Cron Entry Point
pub/cron.php
The main entry point for Magento cron. System cron should trigger this file.
System Crontab Example:
* * * * * php /var/www/html/pub/cron.php
# Or using bin/magento
* * * * * php /var/www/html/bin/magento cron:run
Cron Job Structure
Cron Class Location
Cron jobs are PHP classes typically located in the Cron folder of a module:
Example Structure:
app/code/Bonlineco/OrderExport/
├── Cron/
│ └── ExportOrders.php
├── etc/
│ └── crontab.xml
└── registration.php
Example Cron Class:
<?php
namespace Bonlineco\OrderExport\Cron;
class ExportOrders
{
protected $logger;
public function __construct(
\Psr\Log\LoggerInterface $logger
) {
$this->logger = $logger;
}
public function execute()
{
$this->logger->info('Cron job started: Export Orders');
// Your cron logic here
// Export orders, send emails, cleanup, etc.
$this->logger->info('Cron job finished: Export Orders');
return $this;
}
}
- Must have
execute()method - No parameters in
execute() - Use dependency injection for dependencies
- Return
$thisorvoid
Configuring Cron Jobs
crontab.xml Configuration
Add a crontab.xml file to your module to register cron jobs:
Location:
app/code/Bonlineco/OrderExport/etc/crontab.xml
Basic Configuration:
<?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="bonlineco_export_orders" instance="Bonlineco\OrderExport\Cron\ExportOrders" method="execute">
<schedule>*/5 * * * *</schedule>
</job>
</group>
</config>
Configuration Elements:
<group id="default">- Cron group (default, index, etc.)name- Unique job identifierinstance- PHP class to executemethod- Method to call (usually "execute")<schedule>- Cron expression (when to run)
Cron Schedule Expression
Understanding Cron Syntax
Cron expressions consist of 5 fields:
* * * * *
│ │ │ │ │
│ │ │ │ └─── Day of week (0-7, 0 and 7 are Sunday)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
Common Examples:
| Expression | Description |
|---|---|
* * * * * |
Every minute |
*/5 * * * * |
Every 5 minutes |
0 * * * * |
Every hour (at minute 0) |
0 0 * * * |
Daily at midnight |
0 2 * * * |
Daily at 2:00 AM |
0 0 * * 0 |
Weekly on Sunday at midnight |
0 0 1 * * |
Monthly on the 1st at midnight |
Cron Groups
Organizing Cron Jobs
Magento uses cron groups to organize and control job execution:
Default Cron Groups:
- default - General purpose cron jobs
- index - Indexing operations
- consumers - Message queue consumers
Configuring Group Settings:
Admin Path: Stores → Configuration → Advanced → System → Cron
Group Configuration Options:
- Generate Schedules Every - How often to generate new schedules
- Schedule Ahead For - How far ahead to schedule jobs
- Missed If Not Run Within - When to mark job as missed
- History Cleanup Every - How often to clean old records
- Success History Lifetime - How long to keep successful jobs
- Failure History Lifetime - How long to keep failed jobs
Cron Area Considerations
Important Area Context
Critical Issue:
All cron jobs execute in the crontab area by default, not frontend or adminhtml.
Problems this causes:
- Observers registered for frontend/adminhtml won't fire
- Area-specific configuration may not load
- Plugins may not work as expected
- Layout XML won't be processed
Solutions:
- Design cron jobs to be area-independent
- Manually set area if needed:
$this->state->setAreaCode('frontend') - Don't rely on frontend/adminhtml observers in cron
- Use global scope observers when possible
Testing and Debugging Cron
Testing Strategies
Method 1: Manual Cron Execution
php bin/magento cron:run
Runs all due cron jobs immediately.
Method 2: Run Specific Group
php bin/magento cron:run --group=default
Method 3: Create Console Command (Recommended)
Why? Makes testing and debugging much easier!
Step 1: Create console command
app/code/Bonlineco/OrderExport/Console/Command/CronRun.php
<?php
namespace Bonlineco\OrderExport\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Bonlineco\OrderExport\Cron\ExportOrders;
class CronRun extends Command
{
protected $exportOrders;
public function __construct(
ExportOrders $exportOrders,
string $name = null
) {
$this->exportOrders = $exportOrders;
parent::__construct($name);
}
protected function configure()
{
$this->setName('bonlineco:cron:export-orders')
->setDescription('Run order export cron job manually');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Starting order export...');
$this->exportOrders->execute();
$output->writeln('Order export completed!');
return 0;
}
}
Step 2: Register in di.xml
<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="bonlineco_cron_export" xsi:type="object">
Bonlineco\OrderExport\Console\Command\CronRun
</item>
</argument>
</arguments>
</type>
Step 3: Run command
php bin/magento bonlineco:cron:export-orders
Method 4: PHPStorm Debugging
- Configure PHPStorm to run PHP Script
- Point to your console command
- Set breakpoints in cron class
- Debug with full IDE support!
Checking Cron Status
Using cron_schedule Table
Magento tracks all cron jobs in the cron_schedule table:
Query Recent Cron Jobs:
SELECT
job_code,
status,
scheduled_at,
executed_at,
finished_at,
messages
FROM cron_schedule
WHERE job_code = 'bonlineco_export_orders'
ORDER BY scheduled_at DESC
LIMIT 10;
Status Values:
- pending - Scheduled but not yet run
- running - Currently executing
- success - Completed successfully
- error - Failed with error
- missed - Didn't run within expected time
CLI Command:
php bin/magento cron:list
Shows all registered cron jobs and their schedules.
Best Practices
Do's
- Keep cron jobs fast and efficient
- Use logging for debugging
- Handle exceptions gracefully
- Create console commands for testing
- Use appropriate cron groups
- Set realistic schedules
- Monitor
cron_scheduletable - Clean up old cron records
Don'ts
- Don't run heavy operations every minute
- Don't rely on frontend/adminhtml area
- Don't forget error handling
- Don't assume system cron frequency
- Don't create long-running jobs (use queues instead)
- Don't skip logging
- Don't test only in production
Common Issues and Solutions
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Cron not running | System cron not configured | Add cron entry to system crontab |
| Jobs always "missed" | System cron runs too infrequently | Increase system cron frequency or adjust job schedule |
| Observer not firing | Wrong area (crontab vs frontend) | Use global observers or set area manually |
| Job runs too often | Schedule expression incorrect | Verify cron expression with crontab.guru |
| Job appears twice | Duplicate configuration | Check for duplicate entries in crontab.xml |
Exam Tips
Key Points to Remember
- Entry point:
pub/cron.phporbin/magento cron:run - Configuration file:
etc/crontab.xml - Cron class location:
Cron/folder in module - Required method:
execute()with no parameters - Cron expression format: 5 fields (minute, hour, day, month, weekday)
- Default area: crontab (not frontend or adminhtml)
- Status tracking:
cron_scheduledatabase table - Common groups: default, index, consumers
- Frequency limit: System cron frequency determines maximum job frequency
- Testing tip: Create console command wrapper for easier debugging
- Configuration: Stores → Configuration → Advanced → System → Cron