spatie/laravel-short-schedule
Run Laravel Artisan commands at sub-minute intervals (every second or even 0.5s). Adds a short-scheduler powered by a ReactPHP event loop, running separately from schedule:run so high-frequency tasks don’t block or get delayed.
Installation:
composer require spatie/laravel-short-schedule
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\ShortSchedule\ShortScheduleServiceProvider"
Define Short Schedule:
In app/Console/Kernel.php, add the shortSchedule method:
protected function shortSchedule(ShortSchedule $shortSchedule)
{
$shortSchedule->command('your:command')->everySecond();
}
Run the Scheduler: Start the short scheduler in production:
php artisan short-schedule:run
Use a process manager (e.g., Supervisor) to keep it running.
Schedule a command to sync data every 5 seconds (e.g., for live updates):
ShortSchedule::command('sync:data')->everySeconds(5);
Sub-Minute Scheduling:
ShortSchedule::command('process:events')->everySeconds(0.5);
Constraints Integration:
when, between):
ShortSchedule::command('clean:cache')
->when(fn() => Cache::size() > 1000)
->everySeconds(30);
Environment-Specific Tasks:
ShortSchedule::command('monitor:health')
->environments(['production', 'staging'])
->everySecond();
Process Isolation:
Symfony\Component\Process). Avoid blocking the event loop with heavy logic—offload to queues.Memory Management:
--lifetime flag to auto-restart the worker (e.g., every 60 seconds):
php artisan short-schedule:run --lifetime=60
Event Listeners:
ShortScheduledTaskStarting) for pre/post-execution logic:
ShortScheduledTaskStarting::dispatch(function ($event) {
Log::info("Starting: {$event->command}");
});
Composite Constraints:
ShortSchedule::command('backup:db')
->between('02:00', '04:00')
->environments('production')
->everyHours(1);
Blocking the Event Loop:
when() closures or event listeners. Example:
// ❌ Bad: Heavy DB query in closure
ShortSchedule::command('sync')->when(fn() => DB::table('large_table')->count())->everySecond();
Overlapping Tasks:
withoutOverlapping() to enforce sequential execution:
ShortSchedule::command('critical:task')->everySecond()->withoutOverlapping();
Maintenance Mode:
ShortSchedule::command('emergency:fix')->everySecond()->runInMaintenanceMode();
Process Manager Quirks:
--lifetime to force restarts:
php artisan short-schedule:run --lifetime=3600
Log Output:
php artisan short-schedule:run --log-file=/var/log/short-schedule.log
Check Process Status:
ps aux | grep short-schedule
Test Locally:
php artisan short-schedule:run directly (without Supervisor) for development.Custom Commands:
ShortSchedule::command(\App\Console\ProcessWebhooks::class)->everySeconds(10);
Shell Commands:
ShortSchedule::exec('php artisan optimize:clear')->everyDay();
Dynamic Scheduling:
$interval = config('app.high_load') ? 0.1 : 1;
ShortSchedule::command('scale:resources')->everySeconds($interval);
top or htop to check CPU/memory usage of the worker.SIGTERM in Supervisor to avoid abrupt kills.Spatie\ShortSchedule\Testing\ShortScheduleFakes.How can I help you explore Laravel packages today?