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>&10 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/schedulerSymfony Scheduler defines schedules DIRECTLY in PHP code – VERSIONED, ALONGSIDE the rest of the application logic, instead of in external server configuration.
<?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_tasksThis 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
| Approach | Properties |
|---|---|
| System cron | Simple, NO extra dependency, but configuration lives OUTSIDE the code – good for very simple, infrequent projects. |
| Symfony Scheduler | Schedules 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.