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