Skip to Content
DocsReferenceScheduled Jobs

Scheduled Jobs

Jiji runs scheduled service commands without a separate worker host or a host crontab. Each run starts in a new one-off container.

The owning jiji-agent evaluates schedules and starts jobs. Jobs continue to run after the operator disconnects.

Configure a Job

Add a crons map to a service. Use each map key as a stable job name.

services: worker: image: ghcr.io/example/worker:latest servers: - app1 - app2 environment: clear: NODE_ENV: production secrets: - DATABASE_URL volumes: - worker_data:/app/data crons: sync-reports: schedule: "7 */2 * * *" command: ["npm", "run", "sync:reports"] remove-expired: schedule: "0 3 * * *" command: ["npm", "run", "remove-expired"] timezone: America/Denver timeout: 30m overlap: forbid missed_runs: skip

Deploy the service after you add, remove, rename, or change a job:

jiji deploy -S worker

Jiji installs cron specifications after the service deployment becomes active and healthy. A failed cron installation does not remove a healthy service deployment.

Schedule Format

The schedule value uses five fields:

minute hour day-of-month month day-of-week

This schedule runs every two hours at minute 7:

schedule: "7 */2 * * *"

Seconds and aliases such as @daily are not supported. The default time zone is UTC.

Set timezone to an IANA name when the schedule uses local wall-clock time:

timezone: America/Denver

Container Context

A cron run inherits these service values:

  • The active deployment image.
  • Environment values and secrets.
  • Files, directories, and volumes.
  • CPU, memory, GPU, device, privilege, and capability values.
  • The project bridge and .jiji DNS resolver.

A cron run does not inherit these values:

  • The service command.
  • Published ports.
  • Proxy routes.
  • Health checks.
  • The service restart policy.

The cron command replaces the service command. Jiji sets --restart=no and gives the container an explicit leased address.

Jiji does not use docker exec or podman exec against the serving container. This separation protects the serving process and gives each run its own result, timeout, logs, and address lease.

Ownership

One agent owns each job. Jiji selects the active and healthy replica with the lowest ordinal.

The owner remains stable until placement changes. Jiji reconciles ownership during deploy, restart, rollback, and scale operations.

Jiji installs a job on the new owner before removal from the former owner. If installation fails, the former owner keeps the last working specification.

Cron specifications and run history are local to the owner. Jiji does not replicate them through catalog anti-entropy.

Outages and Overlap

The first release supports overlap: forbid. Jiji skips a due run when the prior run remains active.

The first release supports missed_runs: skip. Jiji does not replay runs missed while the owning agent was offline.

Jiji does not transfer ownership automatically during an owner outage. This rule prevents two agents from starting the same job without a consensus service.

Timeouts and Results

The default timeout is 1h. A timeout accepts seconds, minutes, or hours:

timeout: 45s timeout: 20m timeout: 2h

The agent records each run as claimed, running, succeeded, failed, timed_out, or skipped. Agent restart recovery finds active cron containers before the scheduler accepts more work.

Completed run metadata remains available for 30 days. Jiji also keeps the latest 100 runs for each job regardless of age.

Completed containers remain for 24 hours so their engine logs stay available. These retention values are fixed in the first release.

Inspect Jobs

Show configured jobs and installation drift:

jiji service cron list jiji service cron list -S worker

Show durable run state:

jiji service cron status jiji service cron status -S worker

Run a Job Now

Start a job without changing its schedule:

jiji service cron run sync-reports -S worker

Stream its output:

jiji service cron run sync-reports -S worker --follow

The command returns an overlap conflict when the job already has an active run.

Read Logs

Read the latest retained run:

jiji service cron logs sync-reports -S worker

Read a specific run:

jiji service cron logs sync-reports -S worker --run <run-id>

Filter or follow output:

jiji service cron logs sync-reports -S worker --lines 100 jiji service cron logs sync-reports -S worker --since 30m jiji service cron logs sync-reports -S worker --follow

The --follow option requires an active run. It cannot be combined with --run.

Current Limits

  • A job runs once per service, not once per replica.
  • Failed runs do not retry automatically.
  • Missed runs do not catch up.
  • Owner failover is not automatic.
  • Retention values are not configurable.
  • Services with network_mode: service:<name> cannot define cron jobs.
Last updated on