Scheduler
| A schedule | |
| Add messages | |
| Run it | |
| One cron line |
A schedule
The Scheduler runs repeated jobs without an extra daemon. A job is a small message object, and a schedule maps each message to a rhythm like every hour or every Monday. The block below is the whole shape: one schedule plus one recurring message.
use Symfony\Component\Scheduler\RecurringMessage; use Symfony\Component\Scheduler\Schedule; $schedule = new Schedule(); $schedule->add(RecurringMessage::every("1 hour", new CleanupMessage()));
Add messages
Each job is a plain PHP object that carries the job settings, and a handler does the work when the message arrives. Keep messages tiny: data in, no services inside, so they stay easy to store and retry.
class CleanupMessage { public function __construct(public readonly int $olderThanDays = 30) { } } class CleanupHandler { public function __invoke(CleanupMessage $message): void { // delete rows older than $message->olderThanDays } }
Run it
Schedules travel through Messenger, so a worker process executes the jobs. Start a worker that listens on the scheduler transport and watch the first run in the terminal before wiring any cron line.
$ php bin/console messenger:consume scheduler_default -vv
Handled 1 message from scheduler_default
One cron line
The worker exits after its time limit, so one cron line restarts it every minute. That single line is the full production setup for small projects: cron wakes the worker, the worker runs due messages, then it exits.
* * * * * cd /var/www/app && php bin/console messenger:consume scheduler_default --time-limit=60
Empty output: cron restarts the worker each minute
Next: Webhooks
Article author: Arthur Isaev