Skip to content

Task Scheduling in Laravel 11+

Problem Statement

In Laravel versions prior to 11, developers used the app/Console/Kernel.php file to define scheduled tasks like cron jobs and recurring commands. However, if you're using Laravel 11 or later and searching for the Kernel.php file, you'll notice it doesn't exist in the default project structure. This can cause confusion when following older tutorials or AI-generated code that references this now-removed file.

The key questions developers face are:

  1. Where do I define scheduled tasks in modern Laravel projects?
  2. What are the recommended alternatives to the Kernel.php file?
  3. How should I structure recurring tasks in Laravel 11+?

Solutions

The Laravel framework streamlined its scheduling approach in version 11 by eliminating the dedicated Kernel.php file. You now have two primary approaches to handle task scheduling.

Primary Method: Using routes/console.php

Recommended Approach
Laravel 11+ consolidates scheduled tasks into the routes/console.php file, following the framework's "slimmed-down" architecture principle.

  1. Create or open routes/console.php
  2. Use Laravel's scheduler facade
  3. Define your command schedule
php
// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')->dailyAt('15:00');
Schedule::command('reports:generate')->weeklyOn(1, '8:00');  // Every Monday at 8 AM

Common scheduling frequency methods:

  • ->everyMinute()
  • ->hourly()
  • ->dailyAt('13:00')
  • ->weekly()
  • ->monthly()
  • ->cron('* * * * *')

When to Use This Method

  • 95% of scheduling use cases
  • Following Laravel's standard conventions
  • Maintaining simplicity in your codebase

Alternative Method: Using bootstrap/app.php

For advanced scenarios where you need programmatic control over scheduling setup during application bootstrapping:

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

return Application::configure()
    ->withProviders()
    ->withRouting()
    // ... other configuration
    ->withSchedule(function (Schedule $schedule) {
        $schedule->command('system:backup')->daily();
        $schedule->call(function () {
            // Run custom task
        })->hourly();
    })
    ->create();

Considerations for This Approach

  1. Use sparingly: This can make your app.php file bloated
  2. Dependency issues: Risk of early dependency loading
  3. Less discoverable: Team members may overlook schedules here
  4. Reserve for tasks that need complex environment checks before registration

Key Changes in Laravel Scheduling

  • No more $commands property: Command auto-discovery handles registration
  • Simplified structure: Schedules live alongside route definitions
  • Reduced boilerplate: No need for schedule() method overrides
  • Maintains full functionality: All scheduling features remain available

Best Practices

  1. Group related tasks: Use name prefixes like reports:* for clarity
  2. Prevent overlapping: Use ->withoutOverlapping() for long-running tasks
  3. Environment constraints: Add ->environments(['production']) where needed
  4. Log outputs: Use ->appendOutputTo(storage_path('logs/task.log'))
  5. Lock mechanisms: Implement ->onOneServer() for multi-server setups

Verifying Your Configuration

After setting up your scheduled tasks, test with:

bash
php artisan schedule:list

This displays all registered cron tasks with their next run times. For detailed output during execution:

bash
php artisan schedule:work

Transition Guide: Migrating from Kernel.php

If upgrading from older Laravel versions:

  1. Copy contents from app/Console/Kernel::schedule()
  2. Paste into routes/console.php
  3. Remove the Kernel file
  4. Update any references to kernel-specific logic
  5. Verify schedules with schedule:list

Additional Resources

By adopting these modern approaches, you'll streamline your task scheduling implementation while maintaining compatibility with Laravel's latest conventions.