SchedulableContext is the context object passed to a Schedulable class’s execute method. Its single purpose is to expose the CronTrigger Id of the running scheduled job via getTriggerId().
The interface
public interface SchedulableContext {
Id getTriggerId();
}
That’s it. No state, no helpers — just one method.
How you use it
public class ReportSender implements Schedulable {
public void execute(SchedulableContext ctx) {
// Query the CronTrigger record for schedule metadata
CronTrigger ct = [
SELECT CronExpression, TimesTriggered,
PreviousFireTime, NextFireTime,
CronJobDetail.Name
FROM CronTrigger
WHERE Id = :ctx.getTriggerId()
];
System.debug('Job ' + ct.CronJobDetail.Name +
' has fired ' + ct.TimesTriggered + ' times.');
// ... do the actual work
}
}
What you can do with the trigger Id
| Action | Example |
|---|---|
| Query schedule metadata | SELECT CronExpression, TimesTriggered, ... |
| Abort the current schedule | System.abortJob(ctx.getTriggerId()) |
| Reschedule the same job with a different cron | abort + System.schedule(...) |
| Audit which schedule fired (when multiple schedules use the same class) | Read CronJobDetail.Name |
A self-aborting “one-shot” pattern
A scheduled job that needs to run once, then de-schedule itself:
public class OneShotJob implements Schedulable {
public void execute(SchedulableContext ctx) {
try {
// ... do the work
} finally {
System.abortJob(ctx.getTriggerId()); // self-cleanup
}
}
}
// Schedule once for 30 minutes from now
Datetime when = Datetime.now().addMinutes(30);
String cron = '' + when.second() + ' ' + when.minute() + ' ' + when.hour() +
' ' + when.day() + ' ' + when.month() + ' ? ' + when.year();
System.schedule('One-time Run', cron, new OneShotJob());
The cron expression includes a specific year and day, so it fires once. getTriggerId() lets the job abort its own schedule after firing.
A rescheduling pattern
If you want to dynamically change the schedule from inside the job:
public class AdaptiveJob implements Schedulable {
public void execute(SchedulableContext ctx) {
// ... work
Boolean needsFasterRun = checkLoad();
if (needsFasterRun) {
System.abortJob(ctx.getTriggerId());
System.schedule('AdaptiveJob', '0 */5 * * * ?', new AdaptiveJob()); // every 5 minutes
}
}
}
What SchedulableContext is not
- Not a reference to user state. It doesn’t carry user info, log context, or arbitrary parameters.
- Not a way to pass arguments to the job. Use constructor params on your class for that:
public class ParamScheduler implements Schedulable { private String mode; public ParamScheduler(String mode) { this.mode = mode; } public void execute(SchedulableContext ctx) { /* use this.mode */ } } System.schedule('My job', '...', new ParamScheduler('prod'));
Common interview follow-ups
- What does
getTriggerId()return? — ACronTrigger.Id— 18-char Salesforce Id. - Is
SchedulableContextpersistent between runs? — No — each fire gets a new context object pointing to the same CronTrigger. - Can I get the schedule name from
ctx? — Indirectly — queryCronJobDetail.NameviaCronTrigger.
Verified against: Apex Developer Guide — SchedulableContext Interface. Last reviewed 2026-05-17.