Skip to content
advanced Phase 106 · Incident Response

Cron Failure

45m
1 problems
Topic Progress 0%

Cron Failure Overview

Common Cron Issues

Failure Types:
├── Cron not running
├── Job timed out
├── Job failed with error
├── Job stuck in running state
├── Schedule not created
└── Job skipped

Impact:
├── Indexing delayed
├── Email not sent
├── Inventory not updated
├── Price rules not applied
└── Cache not cleaned

Cron Configuration

// crontab -e
* * * * * /usr/bin/php /var/www/html/bin/magento cron:run
* * * * * /usr/bin/php /var/www/html/bin/magento setup:cron:run
*/5 * * * * /usr/bin/php /var/www/html/bin/magento cache:clean

// Magento cron groups
// app/code/Vendor/Module/etc/crontab.xml
<config>
    <group id="default">
        <job name="my_custom_job" instance="Vendor\Module\Cron\MyJob" method="execute">
            <schedule>* * * * *</schedule>
        </job>
    </group>
</config>

Debug Commands

# Check cron status
bin/magento cron:status

# Run cron manually
bin/magento cron:run

# Check cron logs
tail -f var/log/cron.log

# Check system cron
grep CRON /var/log/syslog

# Check schedule
bin/magento cron:schedule:run

# List scheduled jobs
bin/magento cron:job:list

Cron Job Debugging

Check Cron Status

# Check if cron is running
ps aux | grep cron

# Check cron service
systemctl status cron

# Check crontab
crontab -l

# Check Magento cron table
mysql -e "SELECT * FROM cron_schedule ORDER BY created_at DESC LIMIT 20;"

# Check for running jobs
mysql -e "SELECT * FROM cron_schedule WHERE status = 'running';"

Identify Failed Jobs

-- Find failed jobs
SELECT job_code, status, created_at, executed_at, finished_at
FROM cron_schedule
WHERE status = 'error'
ORDER BY created_at DESC
LIMIT 10;

-- Find long-running jobs
SELECT job_code, status, created_at, executed_at,
       TIMESTAMPDIFF(SECOND, executed_at, NOW()) as duration
FROM cron_schedule
WHERE status = 'running'
  AND executed_at < DATE_SUB(NOW(), INTERVAL 30 MINUTE);

-- Find jobs that didn't run
SELECT * FROM cron_schedule
WHERE status = 'pending'
  AND scheduled_at < NOW();

Analyze Job Errors

// Check job error logs
$jobLogs = $this->db->fetchAll(
    "SELECT * FROM cron_job_log 
     WHERE job_code = ? 
     AND status = 'error'
     ORDER BY created_at DESC 
     LIMIT 5",
    [$jobCode]
);

foreach ($jobLogs as $log) {
    echo "Error: " . $log['error_message'] . "\n";
    echo "Stack: " . $log['error_stack'] . "\n";
}

Missed Schedules

Find Missed Jobs

-- Find missed schedules
SELECT * FROM cron_schedule
WHERE status = 'pending'
  AND scheduled_at < DATE_SUB(NOW(), INTERVAL 5 MINUTE);

-- Count missed jobs by type
SELECT job_code, COUNT(*) as missed_count
FROM cron_schedule
WHERE status = 'pending'
  AND scheduled_at < DATE_SUB(NOW(), INTERVAL 10 MINUTE)
GROUP BY job_code
ORDER BY missed_count DESC;

Fix Missed Schedules

// Clean up stuck jobs
public function cleanStuckJobs()
{
    // Mark old running jobs as error
    $this->db->update('cron_schedule', [
        'status' => 'error',
        'messages' => 'Job stuck - marked as error'
    ], [
        'status = ?' => 'running',
        'executed_at < ?' => date('Y-m-d H:i:s', strtotime('-1 hour'))
    ]);
    
    // Delete old schedules
    $this->db->delete('cron_schedule', [
        'created_at < ?' => date('Y-m-d H:i:s', strtotime('-7 days'))
    ]);
}

// Generate missed schedules
public function generateMissedSchedules()
{
    $missedJobs = $this->getMissedJobs();
    
    foreach ($missedJobs as $job) {
        $schedule = $this->scheduleFactory->create();
        $schedule->setJobCode($job->getJobCode());
        $schedule->setScheduledAt(date('Y-m-d H:i:s'));
        $schedule->save();
    }
}

Manual Execution

// Execute job manually
public function executeJob($jobCode)
{
    $job = $this->jobFactory->create($jobCode);
    
    try {
        $job->execute();
        
        // Log success
        $this->logJob($jobCode, 'success');
        
    } catch (\Exception $e) {
        // Log error
        $this->logJob($jobCode, 'error', $e->getMessage());
        throw $e;
    }
}

// Execute specific job
bin/magento cron:run --job=my_custom_job

// Execute all pending jobs
bin/magento cron:run --force

Prevention Strategies

Monitoring Setup

// Monitor cron jobs
$monitoring = [
    'cron_running' => [
        'check' => 'ps aux | grep cron',
        'alert' => 'Cron not running'
    ],
    'job_failures' => [
        'query' => "SELECT COUNT(*) FROM cron_schedule WHERE status = 'error' AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)",
        'threshold' => 5,
        'alert' => 'Too many job failures'
    ],
    'missed_schedules' => [
        'query' => "SELECT COUNT(*) FROM cron_schedule WHERE status = 'pending' AND scheduled_at < DATE_SUB(NOW(), INTERVAL 5 MINUTE)",
        'threshold' => 10,
        'alert' => 'Missed schedules detected'
    ]
];

Best Practices

// 1. Add timeout to jobs
public function execute()
{
    set_time_limit(300); // 5 minutes
    
    // Job logic
}

// 2. Add error handling
public function execute()
{
    try {
        // Job logic
    } catch (\Exception $e) {
        $this->logger->error('Job failed', [
            'job' => $this->jobCode,
            'error' => $e->getMessage()
        ]);
        throw $e;
    }
}

// 3. Use locks to prevent duplicate execution
public function execute()
{
    $lock = $this->lockManager->lock('job_' . $this->jobCode);
    if (!$lock) {
        return; // Job already running
    }
    
    try {
        // Job logic
    } finally {
        $this->lockManager->unlock('job_' . $this->jobCode);
    }
}

// 4. Log job execution
public function execute()
{
    $this->logger->info('Job started: ' . $this->jobCode);
    
    // Job logic
    
    $this->logger->info('Job completed: ' . $this->jobCode);
}

Practice Problems

0 / 1 solved
Cron Failure Incident

Cron jobs not running for 2 hours, indexing delayed, emails not sent.

Solution
// Response:
// 1. Check: systemctl status cron
// 2. Find stuck: cron_schedule WHERE status='running'
// 3. Fix: Mark stuck jobs as error
// 4. Resume: bin/magento cron:run
// 5. Verify: Jobs executing correctly
// 6. Prevent: Monitor cron service

Quiz

1. How to check if Magento cron is running?

Question 1 options

2. What causes missed cron schedules?

Question 2 options

3. How to run a cron job manually?

Question 3 options

4. How to prevent duplicate cron execution?

Question 4 options

Flashcards

Question

Cron status check?

Answer

bin/magento cron:status

Question

Missed schedule cause?

Answer

Cron not running or jobs stuck

Question

Manual job execution?

Answer

bin/magento cron:run --job=job_name

Question

Prevent duplicate execution?

Answer

Use locks to prevent concurrent runs

Question

Cron debugging table?

Answer

cron_schedule (status, scheduled_at, executed_at)

Revision Notes

Key Takeaways

  • 1. Check status: bin/magento cron:status
  • 2. Missed schedules: Cron not running or jobs stuck
  • 3. Manual run: bin/magento cron:run --job=job_name
  • 4. Prevent duplicates: Use locks
  • 5. Debug: cron_schedule table

Interview Tips

  • Explain cron debugging process
  • Discuss missed schedule handling
  • Know manual execution commands
  • Understand prevention strategies

Cheat Sheet

Cron Failure

  • Status: bin/magento cron:status
  • Missed: Cron not running or stuck
  • Manual: bin/magento cron:run --job=name
  • Duplicates: Use locks
  • Debug: cron_schedule table