Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ramgude_amol's avatar

Dynamic schedule jobs

I m new to laravel 12, I want to add dynamic job schedules, its depends on table called system in my DB I know to add schedules in routes/console.php but should I add below code, is it best practice to do it or there is better way to do it? I mean is it good practice to add foreach loop or call Model System in routes/console.php file

foreach (System::forSync() as $instance) { Schedule::job(new RunSync($instance)) ->name('run_sync:'.$instance->name) ->daily() ->onOneServer() ->timezone($instance->timezone) ->withoutOverlapping(); }

0 likes
7 replies
Glukinho's avatar

Why not? If your schedule is dynamic, then you should call it dynamically, I think it's fine to have this logic in console.php.

ramgude_amol's avatar

@Glukinho I get code review I m adding raw PHP code in console.php file without class or services , which is not laravel practice also migration fails when my system table migration has not run on any server when commented my console.php code and run migration it run well I need alternate solution for dynamic schedules

Thank You.

Glukinho's avatar

@ramgude_amol Sorry, I don't get the point, what are you trying to achieve?

Show your console.php file which prevents migrations.

martinbean's avatar

@ramgude_amol You should be conditionally adding the tasks when the console kernel is resolved, instead of just stuffing database queries in your service providers (or anywhere else).

So, in the boot method of your AppServiceProvider you could put something like this:

public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->app->resolving(Schedule::class, function (Schedule $schedule) {
            // Query your scheduled tasks here...
            
            foreach ($tasks as $task) {
                $schedule->command($task->command_name)->cron($task->cron_expression);
            }

            return $schedule;
        });
    }
}

This code will only run if the application is being invoked in a command line context (which the scheduled task running is), and only when the Schedule class is being resolved (i.e. by the task runner) and not for any CLI command (such as migrations).

The above code assumes you have some sort of tasks table with a column holding the command to be ran, and another column holding the cron expression (i.e. */15 * * * * for every 15 mintues) that the command should be ran on.

1 like
Glukinho's avatar

@martinbean Can I avoid "running in console" check if I simply put foreach ($tasks as $task) ... inside routes/console.php file?

martinbean's avatar

@Glukinho Dunno. The routes/console.php file is one of the first files I delete when creating a new Laravel application 😂

But I wouldn’t put a database query in that file, just like I wouldn’t put queries in my routes/web.php file.

Snapey's avatar

I have similar in a few projects. Here, each system can have a different schedule for FTP collectiions.

            $systems->each(function($system) use($schedule){
                $schedule
                    ->command('xmlflow:ftpcollect --post --system=' . $system->id)
                    ->cron($system->ftpinterval)
                    ->withoutOverlapping(10);
            });

The ftpinterval in the System model holds a string representing the cron pattern, eg */5 * * * *

Please or to participate in this conversation.