Task scheduling
Register recurring work on a Schedule, then run due tasks with grind. Pair this with a system cron entry that calls ./grind schedule:run every minute, or run ./grind schedule:work as a long-lived process.
Register ScheduleServiceProvider in your application bootstrap.
Quick start
Section titled “Quick start”val schedule = app.resolve(Schedule::class.java)schedule.everyMinute("heartbeat") { ping() }schedule.dailyAt("reports", hour = 8, minute = 0) { buildReports() }schedule.command("custom", "*/15 * * * *") { sync() }Schedule schedule = app.resolve(Schedule.class);schedule.everyMinute("heartbeat", () -> ping());schedule.dailyAt("reports", 8, 0, () -> buildReports());./grind schedule:list./grind schedule:run./grind schedule:work --max=1 --sleep=60Frequency helpers
Section titled “Frequency helpers”| Method | Cron |
|---|---|
everyMinute |
* * * * * |
everyFiveMinutes |
*/5 * * * * |
everyTenMinutes |
*/10 * * * * |
everyFifteenMinutes |
*/15 * * * * |
everyThirtyMinutes |
*/30 * * * * |
hourly |
0 * * * * |
everyTwoHours … everySixHours |
0 */n * * * |
daily |
0 0 * * * |
dailyAt(name, hour, minute) |
minute hour * * * |
weekly |
0 0 * * 0 |
monthly |
0 0 1 * * |
command(name, expression, task) |
Custom 5-field cron |
Cron fields are min hour dom month dow. Supported atoms: *, numbers, lists (0,30), ranges (1-5), and steps (*/n).
Overlap and servers
Section titled “Overlap and servers”Each registration returns a ScheduledEvent you can configure:
schedule.everyFiveMinutes("invoice-sync") { syncInvoices() } .withoutOverlapping(expiresMinutes = 10)
schedule.hourly("cleanup") { purgeTemp() } .onOneServer() // file lock under storage/framework .runInBackground() // virtual thread; schedule:run returns immediately- withoutOverlapping — skip if the previous run still holds the mutex
- onOneServer — file-based lock so only one machine runs the task
- runInBackground — start the task on a virtual thread
grind commands
Section titled “grind commands”| Command | Behavior |
|---|---|
schedule:list |
Show registered event names (and flags) |
schedule:run |
Run events due at the current minute |
schedule:work |
Loop: run due events, sleep (--sleep=60), optional --max ticks |
Typical production setup: system cron * * * * * cd /app && ./grind schedule:run. Use schedule:work when you prefer a single long-lived JVM instead of minute cron.