Scheduler Config

on this page

Pass a command-keyed record to scheduler(). Each key identifies the command to dispatch; one command id can have one schedule.

typescript
scheduler({
  'content.fetch': '5m',
  'content.clear': { cron: '0 3 * * *' },
});
NOTE

Multiple independent schedules for the same command id are not supported. The record shape allows one schedule per key.

For a complete content-refresh setup, see the Live Content Refresh recipe.

Schedule shorthand

A bare string is either a duration or a cron expression:

  • A string with no whitespace is a duration, such as '500ms', '30s', '5m', or '2h'.
  • A string with whitespace is a cron expression and must contain exactly five whitespace-separated fields.

Durations may also be raw millisecond numbers in the object form.

Per-job options

Use an object when a job needs options beyond its schedule:

typescript
scheduler({
  'content.fetch': {
    interval: '5m',
    jitter: '30s',
    retry: {
      forever: true,
      backoff: { initial: '10s', max: '2m', factor: 2 },
    },
    command: { type: 'content.fetch' },
    runOnStart: false,
    enabled: true,
  },
});

The schema reference covers each record value. Input defaults do not include values filled by transforms or the scheduler at runtime; those behaviors are explained below. Requiredness is structural, so read the conditional rules for interval, cron, and retry branches. See configuration reference conventions.

Input type: ScheduleSpec

Required: No

Input default: —

interval

Input type: string | number

Required: No

Input default: —

A duration between interval runs. The next interval is computed when the previous dispatch completes, so interval jobs cannot overlap themselves.

cron

Input type: string

Required: No

Input default: —

A five-field cron expression. Cron schedules stay anchored to wall-clock occurrences. The next occurrence is armed before the current dispatch completes; a command already in progress is skipped rather than queued.

Exactly one of interval and cron is required.

jitter

Input type: boolean | string | number

Required: No

Input default: true

Adds a fresh, positive random delay to every scheduled run and retry, spreading a fleet of kiosks out so they don’t all fire at once.

The true default resolves differently by schedule type:

  • Interval jobs (and retry backoff): up to 10% of the delay being scheduled.
  • Cron jobs: up to 60 seconds. A cron gap can be many hours, so a percentage of it would drag the run far off its wall-clock time; the fixed 60-second cap desyncs a fleet without shifting the occurrence meaningfully. For example, a nightly '0 3 * * *' job still fires within a minute of 3am.

Supply a duration to set a fixed maximum jitter for either schedule type, or false to disable jitter.

retry

Input type: object

Required: No

Input default: —

Failed dispatches retry before the normal schedule resumes. A successful dispatch resets the failure count and backoff. Choose one of two policies:

  • Forever: omit retry, use {}, or set forever: true. Only this policy accepts backoff overrides; it does not accept maxAttempts.
  • Limited: set forever: false and supply maxAttempts. This policy uses the default backoff curve and does not accept backoff overrides.
typescript
scheduler({
  'content.fetch': {
    interval: '5m',
    retry: { forever: true, backoff: { initial: '10s', max: '2m', factor: 2 } },
  },
});

To stop after a fixed number of failed attempts instead:

typescript
scheduler({
  'content.fetch': {
    interval: '5m',
    retry: { forever: false, maxAttempts: 3 },
  },
});

A command rejected because it is already running is an overlap skip, not a failure. It does not consume an attempt or begin backoff.

forever

Input type: false | true

Required: No

Input default: —

Selects the retry policy. Omitting this field selects forever retries; false selects limited retries and requires maxAttempts. The field metadata describes all accepted inputs together; conditional requirements are specified in each policy above.

maxAttempts (limited policy)

Input type: number

Required: No

Input default: —

Required when forever: false, even though it is not required across the combined input schema. Must be a positive integer. Not accepted with forever: true or an omitted forever field; it cannot be combined with backoff.

backoff (forever policy)

Input type: object

Required: No

Input default: —

Available only with the forever policy. Omitted fields use the runtime defaults described in the table, not schema input defaults. initial and max accept duration shorthand or milliseconds; factor must be positive.

typescript
scheduler({
  'content.fetch': {
    interval: '5m',
    retry: { backoff: { initial: '10s' } },
  },
});
Backoff override fields (relative to retry.backoff)
FieldInput typeRequiredInput defaultMeaning
initialstring | numberNo—Initial retry delay; omitted values use 15 seconds.
maxstring | numberNo—Maximum retry delay; omitted values use five minutes.
factornumberNo—Positive backoff multiplier; omitted values use 2.

command

Input type: BaseCommand

Required: No

Input default: —

Overrides the command dispatched for this job. This is useful when the command needs a payload. When omitted, the scheduler dispatches { type: <record key> }.

typescript
scheduler({
  'content.fetch': {
    interval: '5m',
    command: { type: 'content.fetch', force: true },
  },
});

runOnStart

Input type: boolean

Required: No

Input default: false

Dispatches the job immediately when the scheduler starts. When false, the first dispatch occurs after the scheduled delay.

enabled

Input type: boolean

Required: No

Input default: true

When false, the job is never scheduled or dispatched and does not appear in the Scheduler status section. A disabled job is invisible to the runtime commands too: scheduler.pause, scheduler.resume, and scheduler.trigger treat its id as unknown, and a broadcast scheduler.pause/scheduler.resume (no job given) skips it entirely.

Limitations

Schedules and retry state are in memory only. On restart, each job receives a fresh schedule from the current time, and cron occurrences missed while Launchpad was stopped are skipped.