Scheduled Jobs

Scheduled Jobs let you run scripts on a recurring basis without any manual trigger. They're ideal for maintenance tasks, periodic reports, SLA enforcement, and data synchronization.

How Scheduling Works

ScriptForge uses the Forge scheduledTrigger mechanism. The platform fires a scheduled trigger on an hourly interval, and ScriptForge's Master Scheduler checks which jobs are due to run during that cycle.

Master Scheduler Behaviour

Each hourly cycle:

  1. The scheduler wakes up and queries all enabled jobs
  2. It identifies jobs whose next execution time has passed
  3. It runs up to 3 jobs per cycle (to stay within Forge execution limits)
  4. Each job gets up to ~22 seconds of execution time (within the 25-second Forge timeout budget)
  5. Jobs that weren't run this cycle are queued for the next cycle

Important: Because the scheduler runs hourly and can only execute 3 jobs per cycle, scheduling many jobs for the same time may result in some being delayed to the next hour.

Job Configuration

Each scheduled job has:

Field Description
Name Descriptive name for the job
Description What the job does
Schedule When to run (interval-based — hourly is the minimum)
Script JavaScript code to execute
Enabled Toggle on/off

Real-World Scenarios

Scenario: Close stale issues weekly

// Find issues untouched for 30+ days in "Waiting for Customer" status
const stale = WorkItems.search(
  'status = "Waiting for Customer" AND updated < -30d'
);

let closed = 0;
await stale.forEach(async (issue) => {
  await issue.addComment('Closing due to 30 days of inactivity. Reopen if still needed.');
  await issue.transition('Closed');
  closed++;
});

return `Closed ${closed} stale issues`;

Scenario: Generate a daily summary

const created = await WorkItems.count('created >= -1d');
const resolved = await WorkItems.count('resolved >= -1d');
const bugs = await WorkItems.count('type = Bug AND created >= -1d');

console.log('=== Daily Summary ===');
console.log(`Created: ${created}`);
console.log(`Resolved: ${resolved}`);
console.log(`New bugs: ${bugs}`);

Scenario: Enforce SLA — escalate overdue issues

const overdue = WorkItems.search(
  'due < now() AND status != Done AND priority = High'
);

await overdue.forEach(async (issue) => {
  await issue.update(b => b.setPriority('Critical'));
  await issue.addComment('⚠️ SLA breach — priority escalated to Critical.');
});

Execution Limits

Constraint Value
Minimum interval 1 hour (Forge platform limitation)
Jobs per cycle 3
Time budget per job ~22 seconds
Script size limit 100 KB

Viewing Job History

Each job execution is logged in Execution History with the feature type "Scheduled Job". You can filter to see:

  • Which jobs ran and when
  • Success/failure status
  • Console output from each run
  • Duration of execution