Skip to content

Running the runner

Greg Bowler edited this page May 17, 2026 · 2 revisions

In WebEngine applications, the cron runner automatically starts with gt run, and can be executed manually with gt cron.

In standalone applications, the simplest way to use this library is through the bundled CLI command:

vendor/bin/cron

Run it from the project root so it can find the local crontab file and cron/ directory.

Default behaviour

With no flags, the runner:

  • reads ./crontab
  • runs any jobs that are due right now
  • prints the next due time
  • exits

If there is no crontab file, it reports that and exits cleanly.

--watch

Use --watch to keep the process alive:

vendor/bin/cron --watch

In watch mode, the runner sleeps until the next due job, runs it, prints an update, and continues.

This is the usual choice during development if we want the scheduler to stay active in the background.

--now

Use --now when we want to run every job immediately once before normal scheduling begins:

vendor/bin/cron --now

This is useful for checking that the commands themselves work, especially in development.

It can also be combined with watch mode:

vendor/bin/cron --now --watch

--validate

To check the file without running jobs:

vendor/bin/cron --validate

This is helpful in CI, deployment scripts, or just before committing a new schedule.

--explain

To print each crontab line with a plain-English explanation instead of running anything:

vendor/bin/cron --explain

This reads the file, skips comments and blank lines, and prints the original schedule beside a short description of when it runs.

It is a practical way to review:

  • nickname expressions such as @daily
  • second-based schedules such as */10s
  • weekday and month names
  • nth weekday expressions such as SUN#1

--file

To use a file other than ./crontab:

vendor/bin/cron --file crontab.staging

The file is resolved relative to the current working directory.

Reading the output

When jobs run, the CLI prints summaries such as:

  • how many jobs just ran
  • a shortened display name for each job
  • the next scheduled run time
  • the next command due

In watch mode it also prints Waiting... after each cycle.

Child command output

The CLI status messages described above are separate from the command's own stdout and stderr.

By default, the bundled runner discards child process output. This keeps the scheduler output tidy, but it also means echo inside a cron script is not usually the right way to observe success.

If we are embedding the library in PHP ourselves, we can choose a different ScriptOutputMode through JobRepository:

  • ScriptOutputMode::DISCARD
  • ScriptOutputMode::INHERIT
  • ScriptOutputMode::CAPTURE

Using the runner from PHP

The CLI is convenient, but the library can also be used directly:

use GT\Cron\RunnerFactory;

$runner = (new RunnerFactory())->createForProject(__DIR__);
$runner->run();

If we need more control, we can set a callback that receives progress data after each cycle:

$runner->setRunCallback(
	function(
		int $jobsRan,
		?DateTime $nextRun,
		bool $continue,
		array $runCommandList,
		?string $nextCommand,
	):void {
		// Log or display status here.
	}
);

Move on to Static functions and shell commands to see how the command part of each crontab line is interpreted.

Clone this wiki locally