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

flyingL123's avatar

Is there a shorthand to schedule commands to be queued?

I can schedule artisan commands like this:

$schedule->command('emails:send --force')->daily();

I can schedule a queue job like this:

$schedule->job(new Heartbeat)->everyFiveMinutes();

I can queue an artisan command like this:

Artisan::queue('email:send', [
    'user' => 1, '--queue' => 'default'
]);

But, from what I can tell, there is no way to nicely schedule a queued artisan command. In other words, I can accomplish what I need like this:

$schedule->call(function () {
    Artisan::queue('command:name');
})->everyMinute();

But it seems like there should be a better way. Is there any way to use the $schedule->job() method, but pass it a command name?

0 likes
8 replies
_stefanzweifel's avatar
Artisan::queue('email:send', [
    'user' => 1, '--queue' => 'default'
]);

The '--queue' => 'default'-part in your example doesn't automatically queue the artisan command. This is just an option which is passed to the email:send command. The command would then have to read the option and implement the queue itself (https://laravel.com/docs/master/artisan#defining-input-expectations)

May I ask, what exactly you want to accomplish and why? Why do you want to schedule an artisan command?

Why don't you use Jobs? (It seems you already have experience with jobs)

Snapey's avatar

It does seem somewhat of a pointless use case (which is probably why there is no shorthand)

If you have a command to be scheduled and this command requires multiple steps then the command itself should decide if it shoukd queue or not.

For instance, you could write a command to wish all your users Happy New Year, schedule this command to run at midnight, but then the emailer creates a queued job for each mail to be sent.

flyingL123's avatar

@_STEFANZWEIFEL - Hmmm, I don't think that's the case. I think it may just be confusing documentation. Because when I run Artisan::queue('command:name');, I see an instance of Illuminate\Foundation\Console\QueuedCommand pushed onto the queue.

Also, as you can see in the docs the the onQueue and onConnection methods can be chained to the call to Artisan::queue():

Artisan::queue('email:send', [
    'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');

In my case, I have written a command to export some data to an FTP service. Something like php artisan data:export. I want it to be a command so that I can call it manually from the command line when needed (in the same process, not in the background). However, it will mostly be called on a schedule, and sometimes there are errors with the connection. So I wanted to queue the command so it will be retried if there are errors.

What's the best way to do this? I didn't want to create a Job class whose purpose was to trigger the command with Artisan::call(). Maybe I am not thinking about this correctly.

ohffs's avatar

Why not extract the logic of your export/ftp to it's own class - then just call that from both your artisan command and queued job?

flyingL123's avatar

@SNAPEY - In my case, I have written a command to export some data to an FTP service. Something like php artisan data:export. I want it to be a command so that I can call it manually from the command line when needed (in the same process, not in the background). However, it will mostly be called on a schedule, and sometimes there are errors with the connection. So I wanted to queue the command so it will be retried if there are errors.

What's the best way to do this? I didn't want to create a Job class whose purpose was to trigger the command with Artisan::call(). Maybe I am not thinking about this correctly.

flyingL123's avatar

@OHFFS - I could, but then I still have a command and a job doing the exact same thing. I was under the impression the command could just be queued, which is why the Artisan::queue() method and the Illuminate\Foundation\Console\QueuedCommand class exist.

Snapey's avatar

your command should queue the job and your scheduler should call the command.

flyingL123's avatar

@SNAPEY - Ok, that makes sense, but I am still confused about one thing. If the command queues the job, is there any way for me to run the logic in the Job without hitting the queue. If I want to go to the command line and manually run the command with artisan, how can I set it up so the command doesn't always hit the queue, but instead just runs the code in the current process?

Should I add a 'queue' option to the command, and maybe have the default set to 'sync', so it runs immediately if no queue is specified?

Please or to participate in this conversation.