How to Schedule Batch Apex: System.schedule, scheduleBatch and Cron

Header image: Schedule Batch Apex, a code editor showing System.schedule with a 2 AM cron expression and System.scheduleBatch running once in 60 minutes.

Hey friends,

To schedule Batch Apex, write a class that implements Schedulable and calls Database.executeBatch in its execute method, then schedule it with System.schedule and a cron expression or from the Schedule Apex page in Setup. For a single future run, System.scheduleBatch schedules the batch class directly, no Schedulable class needed.

Everything below comes from the Apex Scheduler and Use Batch Apex pages of the Apex Developer Guide. Scheduling shows up on the Platform Developer II exam as part of asynchronous Apex. If you're new to batch classes, start with my Batch Apex guide.

What are the ways to schedule a batch job?

OptionRepeats?Needs a Schedulable class?Best for
System.schedule with cronYesYesNightly or weekly jobs set from code
Schedule Apex page in SetupYes (weekly, monthly or a cron expression)YesSetting a recurring time without code
System.scheduleBatchNo, runs onceNoOne run in N minutes, or chaining with a delay

How do you write the Schedulable class?

Schedulable has one method, execute, which must be public or global. Salesforce recommends keeping it thin: just start the job and put the real work in a separate class.

NightlyCleanup.cls
1public with sharing class NightlyCleanup implements Schedulable {
2    public void execute(SchedulableContext sc) {
3        Database.executeBatch(new CloseStaleCases(), 200);
4    }
5}

How do you schedule it with a cron expression?

Call System.schedule with a unique job name, the cron string and an instance of the class:

Anonymous.apex
1String cron = '0 0 2 * * ?';  // 2 AM every day
2Id jobId = System.schedule('Nightly case cleanup', cron, new NightlyCleanup());

The method returns the CronTrigger ID. The job name must be unique, or you get System.AsyncException: The Apex job named ... is already scheduled for execution. Schedules use the running user's time zone.

Apex cron expression examples: 0 0 2 * * ? runs daily at 2 AM, 0 0 10 ? * MON-FRI runs weekdays at 10 AM, 0 0 22 ? * 6L runs the last Friday of each month at 10 PM.

Seven fields: seconds, minutes, hours, day of month, month, day of week, optional year.

The ? rule: you can't set both day of month and day of week. Put ? in one of them. Other special characters: L for last, W for nearest weekday, and # for the nth weekday (2#1 is the first Monday). Salesforce doesn't allow a job to be scheduled more than once an hour with a single expression.

Can you schedule it without code?

Yes. Per Salesforce Help: from Setup, open Apex Classes and click Schedule Apex. Pick the Schedulable class, then choose Schedule Builder (weekly on chosen days, or monthly on a date or a day like the second Saturday) or enter a Cron Expression. Set start and end dates and a preferred start time, then save.

Afterward you can reschedule, pause, resume or delete the job from the All Scheduled Jobs page, and see run details like pass or fail and records processed on the Apex Jobs page.

When should you use System.scheduleBatch?

When you want a batch to run once, a set number of minutes from now. It takes the batch instance, a job name, the delay in minutes and an optional scope, and it returns the CronTrigger ID:

Anonymous.apex
1String cronId = System.scheduleBatch(new CloseStaleCases(), 'Close cases once', 60, 200);
2CronTrigger ct = [SELECT TimesTriggered, NextFireTime FROM CronTrigger WHERE Id = :cronId];

While it waits, scheduled Apex limits apply. Once it's queued (Holding or Queued), batch limits apply instead. You can cancel it before it starts with System.abortJob and the returned ID.

Cert Lab by Nick Frates

Let the Platform Developer II Cert Lab test you to success

Practice questions on async Apex choices, scheduling, limits and testing, each one explained.

Start the Platform Developer II Cert Lab for $9.99 →

Not ready to buy? Try a free lesson and see how fast you learn.

What are the Apex Scheduler limits?

  • 100 scheduled Apex jobs at one time (Developer Edition orgs allow 5 scheduled classes).
  • Async executions per 24 hours: 250,000 or 200 times user licenses, whichever is greater, shared with batch, Queueable and future methods.
  • While a class has active scheduled jobs, you can't edit it (or classes it references) in the Setup UI. Deploying through the Metadata API can be enabled to update it.
  • Execution can be delayed based on service availability. The time you set is the earliest it runs.

How do you test a scheduled job?

Schedule it between Test.startTest and Test.stopTest. After stopTest, the scheduled execute runs, and you can query CronTrigger to check the expression and that it hasn't fired yet:

NightlyCleanupTest.cls
1@IsTest
2private class NightlyCleanupTest {
3    @IsTest static void schedulesTheJob() {
4        String cron = '0 0 2 * * ?';
5        Test.startTest();
6        Id jobId = System.schedule('Test cleanup', cron, new NightlyCleanup());
7        Test.stopTest();
8        CronTrigger ct = [SELECT CronExpression, TimesTriggered FROM CronTrigger WHERE Id = :jobId];
9        Assert.areEqual(cron, ct.CronExpression);
10    }
11}

What scheduling mistakes should you avoid?

  • Scheduling from a trigger. Bulk loads can add jobs past the 100 limit. Salesforce warns to use extreme care.
  • Putting heavy logic in execute of the Schedulable class. Keep it to starting the batch.
  • Setting both day fields. One of day of month or day of week must be ?.
  • Reusing a job name. Names must be unique among scheduled jobs.
  • Fixed schedules for jobs with variable run time. Salesforce suggests chaining batch jobs to avoid overlaps.

A bit about how I study. Focus on Force was my favorite resource on the way to 17 Salesforce certs. I started the traditional way, reading the study guide first and testing second, but rapid-fire practice tests are what actually made things stick. That's the loop Cert Lab is built on: quick questions, then explanations with current links, then go again.

FAQ

Can you schedule Batch Apex every 15 minutes?

Not with a single cron expression. Apex doesn't allow a job to be scheduled more than once an hour that way. Teams either create several hourly jobs offset by 15 minutes or chain jobs with System.scheduleBatch from finish.

What does System.scheduleBatch return?

The scheduled job ID, a CronTrigger ID, which you can query or pass to System.abortJob.

Does the scheduler respect user permissions?

No. The scheduler runs as system, so all classes run whether or not the user has permission to run them.

What's the max number of scheduled jobs?

100 at one time in a production org.

Where should you go next?

Nick Frates, a senior Salesforce developer with 17 certifications, built the Platform Developer II Cert Lab at nickfrates.com: rapid-fire practice questions for every exam section, each answer explained.

Cert Lab by Nick Frates

Let the Platform Developer II Cert Lab test you to success

Lessons, flashcards, a quiz for each of the five exam sections and full practice exams, every answer explained.

Start the Platform Developer II Cert Lab for $9.99 →

Not ready to buy? Try a free lesson and see how fast you learn.

Hope this helps!

Best,

Nick

Keep reading

See all posts →

Salesforce Saturdays

Join 1,033 Salesforce pros getting one 10-minute tip on Salesforce tech or career growth every Saturday.