Laravel Task Scheduling
if you want to run a task or a job at a certain time automatically in Laravel you can use task scheduling. we used to write cron jobs to handle this but cron jobs are not written in the source code and for every change we needed to log into the shared hosting or SSH into the server.
with task scheduling in Laravel, we define our jobs, define a time and they run at the proper moment.
tasks are written in app\console\kernel.php
inside the schedule command.
let’s say we want to email our newsletter subscribers every day and let them know there is a new blog post.
the simplest way to do that is by using the call()
method. like so:
use App\Mail\PostPublished;
use App\Models\User;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Mail;
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
$subscibers = User::where('is_subscriber', true)->get();
Mail::to($subscibers)->send(new PostPublished());
})->daily();
}
}
you can schedule artisan commands too:
$schedule->command('app:email-subscribers')->daily();
or run a shell command:
$schedule->exec('myscript.sh')->hourly();
Define the Frequency
as you saw in the previous examples we specify the frequency of the task by using a method like daily()
or hourly()
after call, command, or exec()
method.
$schedule->command('app:ping-services')->hourly();
there are more methods for defining the frequency. here are a few of them:
- daily()
- dailyAt()
- hourly
- hourlyAt()
- weekly()
- weeklyOn()
- yearly()
- yearlyOn()
you can check out the full list here in the Laravel documentation.
Set TimeZone for the Task
if we want the task to run based on a different timezone other than the default timezone of the Laravel app, we have to use the timezone()
method:
$schedule->command('db:backup')->dailyAt('14:30')->timezone('Europe/London');
there are a few more methods that help us create custom schedules easily:
$schedule->exec('myscript.sh')->weekly()->wednesdays();
in the above code using wednesdays() method after weekly() we told laravel to run this script every Wednesday.
here are a few of these methods:
- weekdays(): run on weekdays
- weekends(): run on weekends
- when($closure): run based on a condition
- between($startTime,$endTime): run between two specific times
- days(array): run the task on specific days.
By using the when()
method we can run a task if a certain condition is true:
$schedule->exec('myscript.sh')->hourly()->when(function () {
return config('myconfig.script_running_enabled', true);
});
with the days() method, we write an array of days inside the method:
$schedule->exec('myscript.sh')->hourly()->days([1,4]);
every day has number. starts with 0 (Sunday) and ends with 6(Saturday).
Run the Scheduler
to run the tasks we have written we need to have just one cron job in our server that runs schedule:run
artisan command every minute:
* * * * * cd /laravel-app-directory && php artisan schedule:run >> /dev/null 2>&1
I am not going to dive deep into configuring a server. I just want to mention setting up a cron entry.
i am using an Ubuntu server so i use this as an example.
first, install cron:
sudo apt install cron
go to the crontab config:
crontab -e
and add the cron for schedule:run
a command.
![](https://phpjunior.com/wp-content/uploads/2023/11/cron-e.jpg)
after that, you don’t need to do anything else. just write schedules in your Laravel app and they will run automatically.