How to Run Laravel Scheduler Tasks Only During Business Hours or Specific Weekdays
Chain the between() method to restrict execution to specific hours and weekdays() or days() to limit tasks to particular days of the week in your console schedule definition.
The Laravel Scheduler provides a fluent, expressive API for defining command schedules without relying on system-level Cron entries. When building enterprise applications with the laravel/framework repository, you often need to restrict background jobs to business hours or specific weekdays to avoid unnecessary server load or inappropriate notification timing.
How the Laravel Scheduler Implements Time Constraints
At the core of the scheduling system is the PendingEvent class, wrapped by PendingEventAttributes located in src/Illuminate/Console/Scheduling/PendingEventAttributes.php. This architecture uses trait composition to mix in frequency management capabilities.
Specifically, the ManagesFrequencies trait defined in src/Illuminate/Console/Scheduling/ManagesFrequencies.php provides the between(), weekdays(), and days() methods that modify the underlying Cron expression and runtime evaluation logic.
Restricting Tasks to Business Hours with between()
The between() method accepts two time strings in HH:MM format and ensures the task only executes when the current server time falls within that inclusive window. According to the source code in ManagesFrequencies.php at line 32, this method stores the start and end times for runtime validation against the current timestamp.
$schedule->command('reports:generate')
->hourly()
->between('09:00', '17:00')
->withoutOverlapping();
Limiting Execution to Specific Days
Using weekdays() for Monday to Friday
The weekdays() method restricts execution to Monday through Friday by appending 1-5 to the day-of-week field of the Cron expression. As implemented in ManagesFrequencies.php at line 404, this effectively excludes Saturday and Sunday from the schedule.
$schedule->command('emails:send')
->dailyAt('08:00')
->weekdays();
Using days() for Custom Day Selection
For more granular control, the days() method accepts an array of numeric day values where 0 represents Sunday and 6 represents Saturday. This allows you to target specific days like Monday, Wednesday, and Friday only.
$schedule->job(new \App\Jobs\WeeklyCleanup)
->dailyAt('02:00')
->days([1, 3, 5]); // Monday, Wednesday, Friday
Combining Business Hours and Weekday Constraints
You can chain multiple constraints to create complex schedules. The scheduler evaluates all conditions cumulatively, meaning the task only runs if all constraints are satisfied simultaneously. This is particularly useful for enterprise applications that should only process data during working hours.
// app/Console/Kernel.php
use Illuminate\Console\Scheduling\Schedule;
protected function schedule(Schedule $schedule): void
{
// Business hours only, weekdays only
$schedule->command('reports:generate')
->hourly()
->weekdays()
->between('09:00', '17:00')
->withoutOverlapping();
// Specific times on specific days
$schedule->call(function () {
// Task logic here
})->dailyAt('10:30')
->weekdays();
// Weekend maintenance jobs
$schedule->job(new \App\Jobs\DatabaseCleanup)
->dailyAt('02:00')
->days([0, 6]); // Sunday and Saturday
}
Summary
- The
ManagesFrequenciestrait insrc/Illuminate/Console/Scheduling/ManagesFrequencies.phpprovides thebetween(),weekdays(), anddays()methods. between('09:00', '17:00')restricts execution to specific hours using runtime validation.weekdays()limits tasks to Monday through Friday by modifying the Cron expression.days([0,1,6])allows custom day selection using numeric values where Sunday is0.- Combine these methods in your
App\Console\Kernelor application schedule definition to create precise, business-hour-aware schedules.
Frequently Asked Questions
How do I prevent a scheduled task from running on weekends?
Use the weekdays() method in your schedule definition. This method modifies the underlying Cron expression to include only Monday through Friday (days 1-5), effectively excluding Saturday and Sunday from execution.
Can I use between() with timezone-aware schedules?
Yes. When you chain timezone('America/New_York') or configure the schedule timezone in your application, the between() method evaluates the time window against the specified timezone. Ensure your application timezone is properly configured in config/app.php or explicitly set on the schedule instance.
What happens if a task is still running when the next interval starts?
By default, Laravel will run overlapping instances simultaneously. To prevent this, chain the withoutOverlapping() method to your schedule definition. This creates a mutex lock that prevents the next execution from starting until the previous one completes, which is essential for long-running business-hour tasks.
How do I schedule tasks for specific days like only Monday and Wednesday?
Use the days() method with an array of numeric day values. For Monday and Wednesday, pass [1, 3] where 1 represents Monday and 3 represents Wednesday. This gives you granular control beyond the standard weekdays() helper.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →