Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Scheduled Tasks and Cron Integration

Scheduled Tasks and Cron Integration

~13 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

Our app:list-overdue-tasks command from chapters 39-40 is useful, but still MUST be called manually – time to have it run AUTOMATICALLY on a schedule, to report overdue tasks daily via email.

The classic approach: system cron

The SIMPLEST approach uses the operating system's cron daemon directly:

# crontab -e
0 9 * * * cd /path/to/project && php bin/console app:send-overdue-reminders --no-interaction >> var/log/cron.log 2>&1

0 9 * * * means "daily at 9:00 AM". --no-interaction from chapter 40 is REQUIRED HERE – a cron job can NEVER answer an interactive prompt. The output redirection (>> ... 2>&1) logs BOTH output channels (normal output AND errors) to a log file, otherwise a cron job's output is lost without a trace.

Achtung: System cron has a practical downside: the configuration lives OUTSIDE the project repository, on the server itself – with several environments (staging, production) or a server change, it must be manually transferred and kept in sync, NOT part of the versioned codebase.

Symfony Scheduler: the modern alternative

composer require symfony/scheduler

Symfony Scheduler defines schedules DIRECTLY in PHP code – VERSIONED, ALONGSIDE the rest of the application logic, instead of in external server configuration.

src/Scheduler/TaskSchedule.php
<?php

declare(strict_types=1);

namespace App\Scheduler;

use App\Message\OverdueReminderMessage;
use Symfony\Component\Scheduler\Attribute\AsSchedule;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\ScheduleProviderInterface;

#[AsSchedule('tasks')]
class TaskSchedule implements ScheduleProviderInterface
{
    public function getSchedule(): Schedule
    {
        return (new Schedule())->add(
            RecurringMessage::cron('0 9 * * *', new OverdueReminderMessage())
        );
    }
}

EXACTLY the same cron syntax ('0 9 * * *') as with system cron above – Symfony internally handles the schedule computation, instead of relying on the operating system's daemon.

Starting the scheduler worker

php bin/console messenger:consume scheduler_tasks

This process runs PERMANENTLY in the background (e.g. via Supervisor or systemd on the production server) and fires the configured messages at the RIGHT time – the OverdueReminderMessage object then lands with an associated message handler, which e.g. calls EXACTLY our app:list-overdue-tasks command logic (or an email variant of it).

Rule of thumb: system cron vs. Symfony Scheduler

ApproachProperties
System cronSimple, NO extra dependency, but configuration lives OUTSIDE the code – good for very simple, infrequent projects.
Symfony SchedulerSchedules VERSIONED in code, dynamically adjustable (e.g. loading a schedule from the database), but needs a PERMANENTLY running worker process – the recommended choice for applications with several scheduled tasks.

Tipp: For THIS chapter, understanding the principle is enough – the full messenger infrastructure (message handlers, transport configuration) would exceed this course's scope and is deliberately mentioned only as an outlook, EXACTLY like the asynchronous mailer sending from chapter 38.