Laravel Task Scheduling: Automate Commands and Jobs

Arlind Musliu cofounder at Lucky Media
Arlind Musliu

January 16, 2024 · 5 min read

Laravel for Beginners: Task Scheduling for Automation

2026 UPDATE - LARAVEL 13

We’re excited to announce that we have updated all of our blog post examples to reflect the new Laravel 13 version! Our previous examples were based on Laravel 10, but with the release of Laravel 13, we wanted to ensure that our readers have access to the most up-to-date information and examples.

Automating your application

When managing an app, there are routine tasks that need to be run periodically, such as cleaning up old posts, optimizing images, or sending out email digests. Performing these tasks manually can be time-consuming and error-prone. Laravel's task scheduling provides an elegant solution for automating such tasks.

Understanding task scheduling in Laravel

Laravel's task scheduler allows you to fluently and expressively define your command schedule within the application itself. Instead of creating multiple Cron entries on your server for each task, you only need to add a single Cron entry that executes Laravel's scheduler. Laravel evaluates all your defined tasks every minute and runs those that are due.

Setting up the cron entry

In production, add this single Cron entry to your server. It calls the Laravel command scheduler every minute:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Replace /path-to-your-project with the actual path to your Laravel application. This single Cron job is the engine that drives the execution of all your scheduled tasks.

Running the scheduler locally

During local development, you do not need to set up a cron entry. Instead, run:

php artisan schedule:work

This command runs the scheduler every minute in the foreground, simulating the cron behaviour. It keeps running until you stop it with Ctrl+C. Use php artisan schedule:run if you want to trigger scheduled tasks just once, as a cron would.

Defining scheduled tasks in Laravel 13

In Laravel 11 and later, the app/Console/Kernel.php file no longer exists. You define all scheduled tasks in routes/console.php using the Schedule facade directly:

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;

// Schedule an Artisan command to run daily
Schedule::command('posts:cleanup')->daily();

// Schedule a closure
Schedule::call(function () {
    // Do something every hour
})->hourly();

Alternatively, you can define schedules in bootstrap/app.php using the withSchedule method:

// bootstrap/app.php
use Illuminate\Console\Scheduling\Schedule;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(...)
    ->withSchedule(function (Schedule $schedule) {
        $schedule->command('posts:cleanup')->daily();
    })
    ->create();

Both approaches work. Using routes/console.php is preferred for most applications as it keeps scheduling logic alongside other route definitions.

Note for Laravel 10 and older: If you are using Laravel 10 or older, schedules are defined in app/Console/Kernel.php inside the schedule method:

// app/Console/Kernel.php (Laravel 10 and below only)
protected function schedule(Schedule $schedule): void
{
    $schedule->command('posts:cleanup')->daily();
}

Frequency methods

Laravel's scheduler provides a variety of methods to specify when tasks should run:

  • ->everyMinute() - Run every minute

  • ->hourly() - Run at the start of every hour

  • ->daily() - Run once per day at midnight

  • ->dailyAt('13:00') - Run every day at 13:00

  • ->weekly() - Run once per week on Sunday at midnight

  • ->monthly() - Run once per month on the first day at midnight

  • ->cron('0 9 * * 1') - Run using a custom cron expression (every Monday at 9am)

Creating custom console commands

To create the posts:cleanup command mentioned above, you would use the command:

php artisan make:command PostsCleanup

This command generates a new command class in the app/Console/Commands directory. You can then define the logic for cleaning up old posts within the handle method of the generated class:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Post;

class PostsCleanup extends Command
{
    protected $signature = 'posts:cleanup';
    protected $description = 'Cleans up old posts from the blog';

    public function handle()
    {
        // Delete posts older than a year
        $deletedPosts = Post::where('created_at', '<', now()->subYear() )
					->delete();

        $this->info($deletedPosts .' old posts have been cleaned up!');
    }
}
Custom Laravel Artisan command

Running the command from the terminal

You can also run the same command from the terminal by entering:

php artisan posts:cleanup

Scheduling queued jobs

You can schedule a queued job to run at a specific interval using Schedule::job(). The job will be pushed onto the queue at the scheduled time and processed by a queue worker:

use App\Jobs\SendWeeklyDigest;
use Illuminate\Support\Facades\Schedule;

// routes/console.php
Schedule::job(new SendWeeklyDigest)->weekly()->mondays()->at('8:00');

You can also specify which queue connection and queue name the job should be pushed to:

Schedule::job(new SendWeeklyDigest, 'emails', 'redis')->weekly();
laravel best framework php

Conclusion

Laravel's task scheduling is a powerful feature that can significantly reduce the manual effort required to maintain your application. By automating routine tasks, you ensure that your application is not only up-to-date but also performing optimally.

Upcoming Articles in the Series

  1. Laravel for Beginners: Error Handling

  2. Laravel for Beginners: Using Queues

  3. Laravel for Beginners: Sending Emails

This article is part of our series Laravel for Beginners: A Step-by-Step Guide to Learn the Concepts.


Bring Your Ideas to Life 🚀

If you need help with a Laravel project let's get in touch.

Lucky Media is proud to be recognized as a leading Laravel Development Agency

Frequently Asked Questions

How do I run the Laravel scheduler locally?

Run php artisan schedule:work in your terminal. This command polls the scheduler every minute and runs any tasks that are due, exactly as a cron would in production. No cron setup is needed locally. Press Ctrl+C to stop it. If you only want to run scheduled tasks once (for debugging), use php artisan schedule:run instead.

Where do I define scheduled tasks in Laravel 13?

In Laravel 11 and later, the app/Console/Kernel.php file is gone. Define your schedules in routes/console.php using the Schedule facade: Schedule::command('your:command')->daily();. Alternatively, use the withSchedule method in bootstrap/app.php.

How do I set up a cron job for Laravel on a server?

Add a single cron entry that runs every minute:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Run crontab -e on the server to edit the crontab and add the line above. Laravel will then evaluate and run all scheduled tasks at their defined frequencies from this single entry.

Can I schedule a queued job in Laravel?

Yes. Use Schedule::job(new YourJob)->daily() in routes/console.php. At the scheduled time, Laravel pushes the job onto the queue and your queue worker picks it up. This is useful when you want the scheduled task to run in the background without blocking the scheduler process. Make sure your queue driver is configured and a worker is running.

Technologies

Laravel
Arlind Musliu cofounder at Lucky Media
Arlind Musliu

Cofounder and CFO of Lucky Media

Stay up-to-date

Be updated with all news, products and tips we share!

Let’s chat

We partner with a limited number of brands each quarter to ensure senior-level attention on every project.

lokman and arlind headshots
Teamwork

Related posts

February 16, 2023

Learn Laravel Routing Techniques for Next.js
Next.js
Laravel