Docs LATEST

Task Scheduling

Define and run scheduled tasks with flexible frequencies.

Scheduling

The scheduler lets you define recurring tasks directly in PHP. No need to manage multiple cron entries-just set up one cron job and define your schedule in code.

Defining Tasks #

Register scheduled tasks in your service provider's boot() method:

class MyServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $schedule = $this->app->make('schedule');
        
        // Run a CLI command daily
        $schedule->command('cache:clear')->daily();
        
        // Run a callback every hour
        $schedule->call(function () {
            // Clean up old sessions
        })->hourly();
    }
}

Running the Scheduler #

Add this to your system cron to run every minute:

* * * * * cd /path/to/velvet && php velvet schedule:run >> /dev/null 2>&1

The scheduler checks which tasks are due and runs them.

Scheduling Commands #

Run any CLI command on a schedule:

$schedule->command('cache:clear')->daily();
$schedule->command('sitemap:generate')->dailyAt(3, 0);  // 3:00 AM
$schedule->command('backup:run')->dailyAt(2, 30);       // 2:30 AM

Scheduling Callbacks #

Run arbitrary PHP code:

$schedule->call(function () {
    // Sync data from external API
    $this->apiSync->run();
})->hourly();

// With parameters
$schedule->call([$this, 'cleanupExpiredTokens'], ['days' => 30])->daily();

Frequency Methods #

Every Minute #

$schedule->command('heartbeat:send')->everyMinute();

Hourly #

$schedule->command('stats:calculate')->hourly();

Runs at minute 0 of every hour.

Daily #

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

Runs at midnight (00:00).

Daily at Specific Time #

$schedule->command('backup:run')->dailyAt(3, 0);      // 3:00 AM
$schedule->command('emails:digest')->dailyAt(9, 30);  // 9:30 AM
$schedule->command('cleanup:temp')->dailyAt(23, 45);  // 11:45 PM

Cron Expressions #

Under the hood, frequencies are converted to cron expressions:

Method Expression When
everyMinute() * * * * * Every minute
hourly() 0 * * * * Start of every hour
daily() 0 0 * * * Midnight daily
dailyAt(3, 30) 30 3 * * * 3:30 AM daily

Example: Complete Schedule #

public function boot(): void
{
    $schedule = $this->app->make('schedule');
    
    // Cache maintenance
    $schedule->command('cache:prune')->hourly();
    
    // Daily cleanup
    $schedule->command('logs:rotate')->daily();
    
    // Backups at 2 AM
    $schedule->command('backup:database')->dailyAt(2, 0);
    $schedule->command('backup:files')->dailyAt(2, 30);
    
    // Reports at 6 AM
    $schedule->command('reports:generate')->dailyAt(6, 0);
    
    // Custom cleanup logic
    $schedule->call(function () {
        $this->cleanExpiredSessions();
        $this->pruneOldNotifications();
    })->dailyAt(4, 0);
}

Task Output #

Command tasks run via passthru(), so their output goes to stdout. For logging, redirect output in your cron entry or handle it within the command itself.

Checking Due Tasks #

The scheduler determines if a task is due based on the current time matching the cron expression. Tasks that aren't due are skipped silently.

What's Next #

  • WebCron - trigger scheduler via HTTP for hosts without cron access