Are you sure it's not working? Since the output looks just fine!
Also > /dev/null 2>&1 & means discard all output. So if you expected output from the scheduled command you are not going to see it.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have a task scheduled to run an artisan command, and for some reason schedule:run is not working properly.
Here is my schedule() function:
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')
->hourly();
$schedule->command('mydomain:sendalerts 100')
->everyMinute();
// $schedule->call(function() {
// Mail::raw('Testing from mydomain', function($message)
// {
// $message->to('me@gmail.com')->from('alerts@mydomain.com');
// });
// })->everyMinute();
}
In the console, calling php artisan mydomain:sendalerts 100 works. Calling php artisan schedule:run does not work. However, when the code below is un-commented, calling php artisan schedule:run does send the test email. So schedule:run is working. The command is working. But schedule:run does not successfully call the command.
When I call php artisan schedule:run, here is the console output:
root@mydomain:/var/www/laravel/current# php artisan schedule:run
Running scheduled command: /usr/bin/php5 "artisan" mydomain:sendalerts 100 > /dev/null 2>&1 &
What am I doing wrong??
Are you sure it's not working? Since the output looks just fine!
Also > /dev/null 2>&1 & means discard all output. So if you expected output from the scheduled command you are not going to see it.
Thanks @stayallive. I'm sure it's not working, because the artisan command is meant to send an email. When I call the command directly, it sends the email. When I call schedule:run, it does not. Very frustrating! Everything seems to be working except that it doesn't hah.
Hey, @gregkaleka ! I have same problem. Did you solved it?
You guys have to register your command to the App\Console\Kernel to make it run.
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
'App\Console\Commands\Inspire',
];
As @Ozan has mentioned you need to add it into your kernal
protected $commands = [
]
Yes, App\Console\Kernel.
@rsands, @Ozan thx for your answers guys, but problem is much different.
As declared in topic. I have specific command, that I can successfully run in console with artisan, like:
$ php artisan some:command:to:run
and it works well. (Which means that it registered in commands and not broken at all)
But then, when I put it into my schedule with code:
protected function schedule(Schedule $schedule)
{
//...
$schedule->command("some:command:to:run")
->cron('0 22 2,3,4 * * *');
//...
}
It was not executed 22:00 UTC on Tue, Wed, Thu (server time is UTC) on artisan schedule:run (which runs every minute).
Ohh, sad to hear that you lost some time messing with this small issue. :D
At least you found it. GJ! :p
Can you paste the full kernel.php code?
Thanks Richard
<?php namespace IDF\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
'IDF\Console\Commands\Membership\IndividualExpiration',
'IDF\Console\Commands\Membership\FixExpiration',
'IDF\Console\Commands\Membership\MembershipAudit',
//'IDF\Console\Commands\RenewCompanyMemberships',
//'IDF\Console\Commands\SendCompanyRenewEmail',
'IDF\Console\Commands\CertificationComplete',
'IDF\Console\Commands\ConvertMigrationsCommand',
'IDF\Console\Commands\Courses\CourseScheduler',
'IDF\Console\Commands\Courses\CourseScores',
'IDF\Console\Commands\Courses\CopyQuizAnswers',
'IDF\Console\Commands\Courses\GenerateAllMissingAnswers',
'IDF\Console\Commands\CreditNoteReconcileStripe',
'IDF\Console\Commands\Crud\CrudController',
'IDF\Console\Commands\Crud\CrudModel',
'IDF\Console\Commands\Crud\CrudRepository',
'IDF\Console\Commands\Crud\CrudScript',
'IDF\Console\Commands\Crud\CrudService',
'IDF\Console\Commands\Crud\CrudStack',
'IDF\Console\Commands\DropTables',
'IDF\Console\Commands\GenerateCourseCertificates',
'IDF\Console\Commands\GenerateMembershipCertificates',
'IDF\Console\Commands\Inspire',
'IDF\Console\Commands\InvoiceAudit',
'IDF\Console\Commands\InvoiceReconcileStripe',
'IDF\Console\Commands\LocalGroupRanks',
'IDF\Console\Commands\LocalGroupWarnings',
'IDF\Console\Commands\MigrateAliases',
'IDF\Console\Commands\Subscription\SubscriptionConfirmation',
'IDF\Console\Commands\Sitemap',
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')
->hourly();
$schedule->command('local-group:warnings')
->dailyAt('06:00');
$schedule->command('local-group:ranks')
->dailyAt('04:00');
$schedule->command('certification:complete')
->weeklyOn(4, '18:00');
$schedule->command("courses:schedule")
->dailyAt('14:00');
$schedule->command("subscription:confirmation")
->daily();
// Regenerate sitemap weekly
$schedule->command("sitemap")
->weekly();
$schedule->command("membership:expiration:individual")
->cron('0 22 2,3,4 * * *');
}
}
@Ozan no luck still, I added some debug/logging for it and may be spot problem during this night, will see. :(
Have you checked the laravel logs?
Is there an inspire command in there every hour?
@Snapey I'm running it with forge, and looks like forge has only last run log. so it's not so easy to catch it :(
@Electronick could you show the code for the sendalerts command?
@rsands sorry, but I don't think it can be helpful.
The problem is why schedule not running correct artisan tasks.
Few things about this command:
It extends \Illuminate\Console\Command
it implementing method handle
Using global Log and method $this->output->write().
@Snapey I moved that command to regular server's cron to get logs, and spotted it runs [Thu Oct 1 11:00:01 UTC 2015] Running scheduled command: /usr/bin/php5 artisan inspire > /dev/null 2>&1 &
But I'm not sure if it executed correctly, because schedule catches output and sends it to /dev/null :(
So your schedule is being triggered then every minute, and triggering the inspire task per hour.
Strip it back a bit and log that your job is being run by just writing to the log file in the job. Temporarily change your schedule to run the task every few minutes.
change the cron to write the output to a log file instead of dev/null ??
@Electronick , I had the same problem AND FOUND THE SOLUTION. In my case, the cron are executed under the root account, but my tests not. So when I run the test, it work fine (call the command directly), but when I run the command under the root I got a php error . In my case, it happen because the php in the root user are another version, so the command don't work.
Hope this help you!
@gregkaleka did you ever solve this?
Hi @gregkaleka, did you solve this problem?
i got some issue here, I have 2 scheduler command and only the first command executed.
$schedule->command('inspire')
->everyMinute()
->appendOutputTo($path);
$schedule->command('queue:work database --daemon --sleep=3 --tries=3')
->everyFiveMinutes()
->withoutOverlapping()
->appendOutputTo($path);
any advice?
@imansyaefulloh have you tried it without the withoutOverlapping ?
It uses a lock file which can get left behind if your job crashes. It then won't ever run that second task because of the lock.
Hi @Snapey,
i'm trying using withoutOverlapping like this, but still not work.
$schedule->command('inspire')
->everyMinute()
->withoutOverlapping()
->appendOutputTo($path);
$schedule->command('queue:work database --daemon --sleep=3 --tries=3')
// ->everyFiveMinutes()
->everyMinute()
->withoutOverlapping()
->appendOutputTo($path);
No, try it without withoutOverlapping
If that works, then you need to track down the lock file and delete it. Its probably in the storage folder
@Snapey, thank you, now its working,
The reason i'm using "withoutOverlapping" in my previous code is because the documentation says "By default, scheduled tasks will be run even if the previous instance of the task is still running. To prevent this, you may use the withoutOverlapping method"
Its that okay to run this (queue:work database --daemon --sleep=3 --tries=3) without using "withoutOverlapping"? coz I dont want it to create multiple instance of queue:work every time this schedule executed.
do I need to executed "queue:restart" before queue:work?
Please give me some advice, i'm new using queue and scheduling.
@imansyaefulloh I'm not saying don't use withoutOverlapping just that you can get in a situation where it no longer works because a previous run has left the file behind. I don't know the mechanism but it seems a little flawed.
Perhaps you could implement the same within your own task, but check a timestamp in the lock file and reset it if its more than x minutes old.
I had the same problem. Task were running from command line but not with the schedule.
My problem was the Cron entry that I added to the server: "* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1"
"path/to/artisan" - needs to be full path to project + "/artisan" - only like that worked for me.
The lock files for scheduling jobs defined with withoutOverlapping() method are created as /storage/framework/schedule-*
Please check the directory /storage/framework/ for such files and delete them to unlock the jobs.
I'm also having this same problem. Happened right after converting our AWS instance from micro to small (no other changes). Suddenly the scheduler never executes after the first time.
In other words, if the schedule is set to every minute in Forge, it runs once and then never appends the logs (it is set to append output) and doesn't trigger the thenPing() method to notify Envoyer after that first run.
This is affecting all commands, all of which run fine if they are given their own cronjob.
When I check for any /storage/framework/schedule-* lock files, I find nothing to delete.
Nothing in the Laravel log files showing a problem.
Any ideas?
Solved this by changing the cronjob from php /home/forge/default/artisan schedule:run to php /home/forge/default/current/artisan schedule:run
This allowed the Laravel scheduler to run correctly. However, the methods thenPing and pingBefore still never actually do their job.
To fix that, I had to manually add this line after each command:
$schedule->command('job-schedule:dispatch')
->everyMinute()
->runInBackground()
->withoutOverlapping()
->sendOutputTo(storage_path('logs/commands/job_scheduler.log'), true)
->pingBefore('http://beats.envoyer.io/heartbeat/SoMeRaNdOmHaSh');
(new Client())->get('http://beats.envoyer.io/heartbeat/SoMeRaNdOmHaSh');
Why the built-in ping methods don't work is a mystery. Would love to know why.
Please or to participate in this conversation.