Skip to main content

SF-0399 · Scenario · Medium

How can we schedule the apex class?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

Two ways:

  1. System.schedule(jobName, cronExpression, instance)Apex code, deterministic, deploys with the org.
  2. Setup → Apex Classes → Schedule Apex — point-and-click UI, fine for one-off setups.

1. Apex — System.schedule

System.schedule(
    'Nightly Stale Case Cleanup',          // friendly name
    '0 0 2 * * ?',                          // cron: 2 AM every day
    new NightlyCleanupSchedulable()         // your Schedulable instance
);

System.schedule returns the CronTrigger.Id. Stash it if you want to programmatically abort later.

The class must implement Schedulable:

public class NightlyCleanupSchedulable implements Schedulable {
    public void execute(SchedulableContext ctx) {
        Database.executeBatch(new StaleCaseCloserBatch(), 200);
    }
}

2. Setup UI

  1. Setup → Apex Classes.
  2. Click Schedule Apex (top-right).
  3. Fill in:
    • Job Name
    • Apex Class (picklist — only Schedulable classes show)
    • Frequency (weekly / monthly / specific days)
    • Start / End Date, Preferred Start Time
  4. Click Save.

Salesforce builds the cron expression from your selections. It’s limited — you can express daily/weekly/monthly but not arbitrary cron like “every 5 minutes.” For complex schedules, use System.schedule from Apex.

Cron expression quick reference

Format: Seconds Minutes Hours Day-of-Month Month Day-of-Week [Year]

CronMeaning
0 0 2 * * ?2:00 AM every day
0 0 * * * ?Every hour on the hour
0 */15 * * * ?Every 15 minutes
0 0 8 ? * MONMondays at 8 AM
0 30 6 1 * ?6:30 AM on the 1st of every month
0 0 0 ? * SUNMidnight every Sunday

The ? placeholder means “no specific value” — you must use it in either day-of-month or day-of-week, never both.

Pre-built helpers

For simple “every N minutes” schedules, Apex provides convenience methods:

// Run MyBatch once in 30 minutes
System.scheduleBatch(new MyBatch(), 'MyBatch Once', 30, 200);

scheduleBatch builds the cron for you and creates a Schedulable wrapper automatically.

Schedule once per Apex class? Or many times?

You can schedule the same class under multiple names with different cron expressions:

System.schedule('Quarterly Report Q1', '0 0 6 1 1 ?', new QuarterReport());
System.schedule('Quarterly Report Q2', '0 0 6 1 4 ?', new QuarterReport());
System.schedule('Quarterly Report Q3', '0 0 6 1 7 ?', new QuarterReport());
System.schedule('Quarterly Report Q4', '0 0 6 1 10 ?', new QuarterReport());

Four separate CronTrigger rows, all pointing to the same class. Each counts against the 100-scheduled-job limit.

Limits to know

LimitValue
Active scheduled jobs (Schedulable) in the org100
System.schedule calls per transaction250
Per-job cron resolution1 minute (seconds field accepted but ignored in practice)

Common interview follow-ups

  • Where do I find the JobId after scheduling?System.schedule returns it. You can also query CronTrigger by name.
  • Can I update the schedule? — Not directly. Abort the existing CronTrigger and call System.schedule again with the new expression.
  • Does deploying overwrite the schedule? — No. The schedule is data (a CronTrigger), not metadata.

Verified against: Apex Developer Guide — Scheduled Apex. Last reviewed 2026-05-17.