Skip to main content

Cron Scheduling

Runix includes a built-in cron scheduler for running recurring tasks.

Implementation​

Located at internal/scheduler/:

FileResponsibility
scheduler.goScheduler — wraps robfig/cron, manages job registration and lifecycle
job.goJob — executes commands, tracks run count and last run time

Uses robfig/cron/v3 with seconds support enabled.

Configuration​

cron:
cleanup:
schedule: "0 */6 * * *"
command: "rm -rf /tmp/old-*"
enabled: true
cwd: /tmp
env:
CLEANUP_MODE: aggressive
timeout: 5m

backup:
schedule: "0 2 * * *"
command: "pg_dump mydb > /backups/mydb-$(date +%Y%m%d).sql"
enabled: true
timeout: 30m

health-report:
schedule: "*/30 * * * *"
command: "curl -s http://localhost:8080/health > /tmp/health-report.txt"
enabled: false

Schedule Format​

Runix supports both 5-field and 6-field cron expressions:

5-field (standard)​

┌──────── minute (0-59)
│ ┌────── hour (0-23)
│ │ ┌──── day of month (1-31)
│ │ │ ┌── month (1-12)
│ │ │ │ ┌ day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *

When a 5-field expression is provided, Runix auto-prepends 0 for the seconds field.

6-field (with seconds)​

┌──────── second (0-59)
│ ┌────── minute (0-59)
│ │ ┌──── hour (0-23)
│ │ │ ┌── day of month (1-31)
│ │ │ │ ┌ month (1-12)
│ │ │ │ │ ┌ day of week (0-6)
│ │ │ │ │ │
0 * * * * *

Common Expressions​

ExpressionMeaning
*/5 * * * *Every 5 minutes
0 */6 * * *Every 6 hours
0 2 * * *Daily at 2:00 AM
0 0 * * 0Every Sunday at midnight
0 0 1 * *First day of every month
*/30 * * * * *Every 30 seconds (6-field)

Job Execution​

Jobs execute via sh -c <command> with optional working directory and environment overlay:

cmd := exec.CommandContext(ctx, "sh", "-c", job.Config.Command)
cmd.Dir = job.Config.Cwd
cmd.Env = buildCronEnv(job.Config.Env)

Timeout​

If timeout is set, the job context is cancelled after the duration. The process receives a kill signal.

Environment​

The job inherits the host's environment with overlay variables from env. Overlay variables replace existing ones with the same name.

Runtime Management​

OperationMethodCLI
Register jobscheduler.AddJob(cfg)Config file
Remove jobscheduler.RemoveJob(name)Config file change
Enable jobscheduler.EnableJob(name)runix cron start <name>
Disable jobscheduler.DisableJob(name)runix cron stop <name>
Trigger manuallyscheduler.RunJob(name)runix cron run <name>
List jobsscheduler.ListJobs()runix cron list

JobRunner Interface​

The scheduler uses the JobRunner interface for dependency injection:

type JobRunner interface {
RunJob(cfg types.CronJobConfig) error
}

When no runner is provided, jobs fall back to direct execution via exec.CommandContext.

What's Next​