How to Set Up a Cron Job in Your Laravel App

Share this article

Laravel cron jobs

There are times when your application needs to run administrative tasks periodically on the server. Whether you want to send out emails to your users or clean up the database tables at the end of the day, you will need a task scheduling mechanism to take care of the tasks, when it’s time. Cron is a task scheduler in unix-like systems, which runs shell commands at certain intervals. This article is not meant for introducing Cron, but since it is a key concept in our tutorial, we’ll will describe the basics of how it works. A clock

Cron basics

Cron is a task scheduler daemon which runs scheduled tasks at certain intervals. Cron uses a configuration file called crontab, also known as cron table, to manage the scheduling process. Crontab contains cron jobs, each related to a specific task. Cron jobs are composed of two parts, the cron expression, and a shell command to be run:
* * * * * command/to/run
Each field in the above expression (* * * * *) is an option for setting the schedule frequency. It is composed of minute, hour, day of month, month and day of week in order of the placement. The asterisk symbol refers to all possible values for the respective field. As a result, the above cron job will be run every minute in the day. The following cron job is executed at 12:30 every day:
30 12 * * * command/to/run
This is just the tip of the Cron iceberg; to learn more about it, you might want to visit the wikipedia page. In PHP powered applications, administrative tasks are normally standalone PHP scripts which are run in CLI mode. These scripts are written for performing different jobs at certain times. However, we can’t do much without the power of other PHP libraries and frameworks. In this article, you will learn how to use the Laravel framework to create robust PHP scripts for the command line and schedule them right from the source code.

Creating Commands in Laravel

Creating a command in PHP is as simple as creating a PHP script, then running it in the command line, using the php command:
php somefile.php
As you can see, the file is passed as an argument to the command php. Whether your application has been developed in Laravel, or you just want to use its facades and helpers to create your scripts, you will need to bootstrap Laravel before using it. However, there’s a better alternative to this: creating a Laravel Artisan command. When using Artisan commands, we will have access to all features of Laravel, including helpers, facades, and other Artisan commands, just to name a few. We’re not going to go into the details of Artisan commands here, as they’re beyond the scope of this tutorial, but let’s discuss the basics, just to get started. We’ll will be using the latest version of Laravel, which is 5.1 at the time of writing this article. We use the make:console Artisan command to generate a command class skeleton to work with. As an example, we’re going to create a command which sends a happy birthday SMS message to our users on their birthday.
$ php artisan make:console HappyBirthday --command=sms:birthday
The above command will create a class named HappyBirthday in a file of the same name in the app/Console/Commands directory. We also picked a name for the command via the command option. This is the name that we’ll use when calling the command. Now let’s open the file, and see what we have so far. There are several properties and methods inside the class that build the command’s backend:
<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class HappyBirthday extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'sms:birthday';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
    }
}
For the $description, we can put a simple description of what the command does when executed.
protected $description = 'Sends a Happy birthday message to users via SMS';
In Laravel 5.1
, whenever a command is executed in the terminal, the handle method of the command class is called. That’s where we need to put our logic. In our case, to send a birthday message to users on their birthday, we can modify handle method like so:
<?php
// ...
public function handle()
{
  User::whereBirthDate(date('m/d'))->get(); 

  foreach( $users as $user ) {
    if($user->has('cellphone')) {
    SMS::to($user->cellphone)
       ->msg('Dear ' . $user->fname . ', I wish you a happy birthday!')
       ->send();
    }   
}  

$this->info('The happy birthday messages were sent successfully!');

}
Once the command is finished, we need to register it with Artisan, so that it will be available in the terminal. To do this, we just need to add the command’s classname to the commands array of theKernel class, which is located at app/Console/Kernel.php:
<?php
class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        // ...
        'App\Console\Command\HappyBirthday'
    ];

    // ...
If we run php artisan list in the terminal, we will see our command’s description:
$ php artisan list

...
sms
  sms:birthday        Sends a Happy birthday to users via SMS
...
It’s a good habit to namespace the command names. This will help us categorize them based on their usage. As a result, whenever we run the command in the terminal, a happy birthday message would be sent to the matched group of users:
$ php artisan sms:birthday

The happy birthday messages were sent successfully!
This is just a hypothetical use case. For a more concrete example, see Younes Rafie’s post about a minification command.

Scheduling the Commands

Here comes the fun part. Let’s schedule a task for running the command we just built. To do this, we’ll use a feature you’ll undoubtedly come to love: Laravel Task Scheduler. The tasks are defined inside the schedule method of the Kernel class. We can add as many Artisan commands as we need by using the command method. Our task, according to its usage, is supposed to be run once a day. So we can use the daily() method like so:
<?php

// ...

protected function schedule(Schedule $schedule)
{   
        $schedule->command('sms:birthday')->daily();
}
We can schedule all the commands right from the schedule method. As the documentation states, there are a variety of schedule frequencies we may assign to the tasks. We’ll list a few of them here, but you may want to read the documentation to see the full list and decide which best suits your circumstances. To run a task every hour every day:
<?php
$schedule->command('myTask')
         ->hourly(); 
To run a task every day at midnight:
<?php
$schedule->command('myTask')
         ->daily(); 
To run a task every day at 9:30:
<?php
$schedule->command('myTask')
         ->dailyAt('09:30'); 
To run a task every week:
<?php
$schedule->command('myTask')
         ->weekly(); 
To run it every month:
<?php
$schedule->command('myTask')
         ->monthly(); 
We can also use a custom cron schedule, like an ordinary cron job expression:
$schedule->command('myTask')
         ->cron('* * * * *');
The above task will be run every minute. To see the full list of options, please refer to the documentation, section Schedule Frequency Options. Laravel also provides a set of schedule constraints, which can be combined with the above methods. For instance, we can schedule a task to be run weekly, but limit it to a certain day and hour.
<?php
$schedule->command('theTask')
         ->weekly()
         ->mondays()
         ->at(12:30); 
or
<?php
$schedule->command('theTask')
         ->weekly()
         ->sundays() 
We can go further and limit the execution of the task to a certain condition, using the when method which accepts a closure. The task will be executed only if the closure returns true.
<?php
$schedule->command('table:clean')
          ->daily()
          ->when(function() {
             return SMS::isWorkingFine();
          });

Starting the Laravel Scheduler

To start the scheduler itself, we only need to add one cron job on the server (using the crontab -e command), which executes php /path/to/artisan schedule:run every minute in the day:
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
Please note that we need to provide the full path to the Artisan command of our Laravel installation. To discard the cron output we put /dev/null 2>&1 at the end of the cronjob expression. To read more about the Scheduler, see the Scheduling chapter in the documentation.

Conclusion

In this tutorial, we made use of Laravel Artisan commands to create terminal commands. Rather than add many cron job entries on the server per task, we only created one which is executed every minute and delegates responsibility to Laravel’s task scheduler. By using custom Artisan commands alongside Laravel’s task scheduler, we can focus on creating the commands and Laravel will take care of the rest. In addition to this, the scheduling frequencies are manageable by other team members since it is now tracked by the version control system. If you have an questions or comments, please post them below and we’ll do our best to reply in a timely manner.

Frequently Asked Questions (FAQs) about Managing Cronjobs with Laravel

What is the purpose of Laravel’s task scheduling?

Laravel’s task scheduling is a powerful feature that allows developers to schedule tasks to run periodically at fixed intervals, such as every minute, hourly, daily, or weekly. This is particularly useful for tasks that need to be performed regularly, such as sending out daily or weekly emails, cleaning up old data, or generating reports. Laravel’s task scheduling is built on top of the Cron system, a time-based job scheduler in Unix-like operating systems, and provides a more user-friendly and flexible way to manage these tasks.

How do I set up a Cron job in Laravel?

Setting up a Cron job in Laravel involves two main steps. First, you need to define the task in the Laravel’s task scheduler. This is done in the schedule method of the App\Console\Kernel class. Here, you can specify the command to run, the frequency at which it should run, and any conditions that need to be met for the task to run. Second, you need to add a new Cron entry on your server that calls the Laravel’s task scheduler every minute. This is done by adding the following line to your server’s Crontab: * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1.

How can I test a Cron job in Laravel?

Testing a Cron job in Laravel can be done using the artisan command-line tool. You can manually run a scheduled task using the artisan schedule:run command. This will run all tasks that are due to run at the current time. If you want to test a specific task, you can call it directly using the artisan command followed by the name of the command. For example, if you have a command named emails:send, you can run it manually using the php artisan emails:send command.

How can I prevent overlapping tasks in Laravel’s task scheduler?

Laravel’s task scheduler provides a simple way to prevent tasks from overlapping. You can chain the withoutOverlapping method onto a task definition to prevent the task from running if it is already running. This is particularly useful for tasks that take a long time to complete and could potentially overlap if they are scheduled to run too frequently.

How can I handle task failures in Laravel’s task scheduler?

Laravel’s task scheduler provides several methods to handle task failures. You can chain the onFailure method onto a task definition to specify a callback that should be run if the task fails. You can also use the pingOnFailure method to send a HTTP request to a specified URL if the task fails. This can be useful for sending notifications or logging failures.

Can I run tasks at specific times in Laravel’s task scheduler?

Yes, Laravel’s task scheduler allows you to run tasks at specific times. You can use the at method to specify the exact time at which a task should run. The time should be specified in 24-hour format. For example, to run a task at 2:30 PM, you would use $schedule->command('emails:send')->dailyAt('14:30');.

Can I run tasks on specific days in Laravel’s task scheduler?

Yes, Laravel’s task scheduler allows you to run tasks on specific days. You can use the mondays, tuesdays, wednesdays, thursdays, fridays, saturdays, or sundays methods to schedule a task to run on a specific day of the week. For example, to run a task every Monday at 1:00 PM, you would use $schedule->command('emails:send')->mondays()->at('13:00');.

How can I view the list of scheduled tasks in Laravel?

You can view the list of scheduled tasks in Laravel using the artisan schedule:list command. This will display a table with the list of tasks, their frequency, their next due time, and their description.

Can I run tasks in the background in Laravel’s task scheduler?

Yes, Laravel’s task scheduler allows you to run tasks in the background. You can chain the runInBackground method onto a task definition to run the task in the background. This is particularly useful for tasks that take a long time to complete and you don’t want to block the execution of other tasks.

Can I run tasks in maintenance mode in Laravel’s task scheduler?

Yes, Laravel’s task scheduler allows you to run tasks in maintenance mode. You can chain the evenInMaintenanceMode method onto a task definition to run the task even if your application is in maintenance mode. This can be useful for tasks that need to run regardless of the application’s status, such as database backups or data synchronization tasks.

Reza LavarianReza Lavarian
View Author

A web developer with a solid background in front-end and back-end development, which is what he's been doing for over ten years. He follows two major principles in his everyday work: beauty and simplicity. He believes everyone should learn something new every day.

croncron joblaraveltask
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week