Mastering Laravel Task Scheduling for Automated Jobs (Compatible with Laravel 10, 11 & 12)

Mastering Laravel Task Scheduling for Automated Jobs (Compatible with Laravel 10, 11 & 12)

BackerLeader posted 3 min read

If you’ve ever wanted your Laravel app to automatically perform tasks — like sending daily reports, clearing logs, or running database cleanups — task scheduling is exactly what you need.

Laravel makes this incredibly easy. No need for messy cron scripts or complex automation tools — everything is neatly handled right inside the framework.

In this post, I’ll walk you through how Laravel’s Task Scheduler works, step-by-step, so you can start automating jobs confidently. Whether you’re using Laravel 10, 11, or 12, this guide has you covered.


What is Task Scheduling in Laravel?

Task Scheduling allows your application to automatically perform repetitive tasks at specific intervals — hourly, daily, weekly, or even every few minutes.

Think of it as Laravel’s built-in personal assistant.

Instead of manually running commands every time, Laravel’s scheduler lets you define everything in code — so tasks just happen, reliably.

For example, you could:

  • Send daily email reports.
  • Clean up old database records.
  • Sync data from APIs.
  • Generate invoices automatically every midnight.

⚙️ Step 1: Understand How the Scheduler Works

Laravel’s scheduler is powered by a single cron job on your server. Once that cron job runs every minute, Laravel handles the rest — deciding which tasks should run and when.

In other words:

One cron job to rule them all.

You don’t have to create multiple cron jobs for different tasks — just one that triggers Laravel’s internal scheduler.


Step 2: Setting Up the Cron Job

First, open your terminal and type:

crontab -e

Then add this line at the end of the file:

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

Here’s what each part means:

  • * * * * * → Run every minute.
  • cd /path-to-your-laravel-app → Change directory to your Laravel project.
  • php artisan schedule:run → Triggers Laravel’s scheduler.
  • >> /dev/null 2>&1 → Silently discard output (to keep logs clean).

Once that’s saved, your Laravel app can automatically run any scheduled tasks you define in code.


Step 3: Create Your First Scheduled Task

All task definitions live inside this file:
app/Console/Kernel.php

Open it and find the schedule() method. You’ll see something like this:

protected function schedule(Schedule $schedule)
{
    // Define your tasks here
}

Now, let’s create a simple example — maybe we want to log a message every hour.

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        \Log::info('Hourly job ran successfully at ' . now());
    })->hourly();
}

That’s it!

Laravel will now automatically log this message every hour.


Step 4: Scheduling Artisan Commands

You can also schedule Artisan commands — for example, to run php artisan backup:run every night:

$schedule->command('backup:run')->dailyAt('01:00');

Or a custom command you’ve written yourself:

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

Laravel 11 & 12 make this even smoother with improved method chaining, so you can easily attach conditions or environments like this:

$schedule->command('queue:work')
         ->withoutOverlapping()
         ->onOneServer()
         ->everyMinute();

Step 5: Scheduling Shell Commands

Sometimes, you may want to run system-level commands, such as clearing logs or syncing files.
You can use the exec() method for that:

$schedule->exec('rm -rf /var/logs/old_logs')->weekly();

Just be careful when using system commands — always double-check your paths and permissions.


Step 6: Adding Notifications and Error Handling

What if something goes wrong during a scheduled task?

Laravel lets you automatically send notifications when tasks fail or succeed.

Example:

$schedule->command('inspire')
         ->daily()
         ->emailOutputTo('*Emails are not allowed*')
         ->sendOutputTo(storage_path('logs/inspire.log'))
         ->onFailure(function () {
             \Log::error('The scheduled Inspire command failed!');
         });

You can also notify through Slack, Telegram, or custom integrations. (Check Laravel’s Notification system for advanced options!)


Step 7: Automating Database Maintenance

Here’s a real-world example — let’s clean up old user sessions daily:

$schedule->call(function () {
    DB::table('sessions')->where('last_activity', '<', now()->subDays(7)->timestamp)->delete();
})->daily();

This automatically deletes inactive sessions every day at midnight — hands-free!


Bonus Tips

Use withoutOverlapping()

Prevents the same job from running multiple times if it hasn’t finished yet.

$schedule->command('emails:send')->everyFiveMinutes()->withoutOverlapping();

Use onOneServer()

Perfect for multi-server environments — ensures the job runs only once.

$schedule->command('reports:generate')->daily()->onOneServer();

Use runInBackground()

Allows Laravel to keep executing other tasks while one runs in the background.

$schedule->command('backup:run')->daily()->runInBackground();

✅ Conclusion

Laravel’s Task Scheduler is one of the framework’s most powerful (and often underrated) features.
By setting it up once, you can fully automate repetitive tasks — whether it’s sending emails, cleaning data, or backing up files.

And the best part? It’s simple, elegant, and works seamlessly across Laravel 10, 11, and 12.

So next time you find yourself running the same command daily, let Laravel do the heavy lifting. ⚙️


Further Reading

More Posts

Laravel 12 & Laravel Cloud: The Next Big Leap in Web Development

Snehal Kadwe - Mar 9

Learn to manage Laravel 10 queues for efficient job handling and implement real-time notifications seamlessly.

Gift Balogun - Jan 1

10 Simplified Laravel 10 Performance Hacks You Can Use Today

Gift Balogun - Apr 30

Building a Rate-Limiting Middleware for Your API in Laravel

Gift Balogun - Oct 8

Protecting Your Laravel API from DDoS Attacks: Best Practices

Gift Balogun - Oct 13
chevron_left