Scheduler
Overview
Pogo Scheduler is a small Caddy app that runs one configured command on every wall-clock minute.
The common Laravel command is:
php artisan schedule:run
The scheduler runs in the FrankenPHP process. It is intentionally small and does not try to be a distributed scheduler.
Status and fit
Pogo Scheduler is experimental. Its best fit is constrained, single-binary, and single-node deployments.
Use it when:
- You run a single VPS or single server.
- You use Docker Compose or a small container setup and want to avoid host cron.
- You run a dedicated singleton scheduler service from the same application image.
- Your framework handles locking, overlap, and task-level safety.
Avoid it when:
- You run production Kubernetes. Use native
CronJobresources. - You scale web replicas without shared application locks.
- You need exactly-once execution without idempotency or locking.
Build
Compile the module into FrankenPHP:
xcaddy build \
--with github.com/dunglas/frankenphp@v1.12.3 \
--with github.com/dunglas/frankenphp/caddy@v1.12.3 \
--with github.com/y-l-g/scheduler/module@main
Caddy configuration
{
frankenphp
pogo_scheduler {
command php artisan schedule:run
dir /var/www/html
timeout 5m
overlap allow
shutdown_grace 30s
}
}
Defaults:
| Directive | Default | Description |
|---|---|---|
command | php artisan schedule:run | Command and arguments to run each minute. |
dir | empty | Optional working directory. |
timeout | 5m | Maximum duration for one command run. |
overlap | allow | Use allow or skip. |
shutdown_grace | 30s | Time to wait for an active command before cancellation. |
Application integration
Laravel
Use the default command and keep Laravel's scheduler definitions in routes/console.php or your normal scheduler setup:
pogo_scheduler {
command php artisan schedule:run
dir /var/www/html
}
When running more than one replica, use Laravel locks such as onOneServer() and withoutOverlapping() with a shared cache backend.
Symfony or custom PHP
Point command at any CLI command that can run once per minute:
pogo_scheduler {
command php bin/console app:run-scheduled-tasks
dir /var/www/html
timeout 10m
overlap skip
}
PHP API
Pogo Scheduler does not expose PHP functions. It is configured entirely through the Caddy global option.
Operations
- Run the scheduler-enabled service as a singleton unless your application uses shared locks.
- Keep scheduled tasks idempotent.
- Use
overlap allowfor Laravel'sschedule:run, especially when sub-minute tasks can keep the command alive for most of the minute. - Use
overlap skiponly when the command itself must never overlap locally. - Set
timeouthigh enough for normal command duration but low enough to prevent stuck processes.
Troubleshooting
- Command never runs: confirm the binary includes
pogo_schedulerand the global Caddyfile block is loaded. - Wrong working directory: set
dirto your application root. - Duplicate scheduled work: run only one scheduler process or add framework-level shared locks.
- Command cancelled during deploy: increase
shutdown_graceor make the command shorter and resumable.