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:
- The scheduler wakes up and queries all enabled jobs
- It identifies jobs whose next execution time has passed
- It runs up to 3 jobs per cycle (to stay within Forge execution limits)
- Each job gets up to ~22 seconds of execution time (within the 25-second Forge timeout budget)
- 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