Print this page

Create a custom schedule for apex jobs

Knowledge Article Number 000002812

When using the UI Scheduled Apex you are restricted to what times and frequency you can select.

Using a schedulable class we can kick off the schedule using the UI and override it with our own schedule.

IE. Run a batch class every 1 hour (we can't do this via Setup)


Class 1: Schedulable class that runs first.. Schedule this class via Setup.

It will cancel the job straight away and then call the batch class which will create the new schedule.


global class AccountScheduler implements Schedulable{
global void execute(SchedulableContext SC){
            // Abort the job you have just scheduled via Setup 
            CronTrigger ct = [SELECT id,CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :SC.getTriggerId()];
            if(ct != null)
        catch(Exception e) 
            System.debug('No jobs scheduled ' + e.getMessage()); 
        AccountBatch acBatch = new AccountBatch();



Class 2: Execute your logic in this class. We will create the new schedule in the finish method.

global with sharing class AccountBatch implements Database.Batchable<SObject> {

global Database.QueryLocator start(Database.BatchableContext BC){

global void execute(Database.BatchableContext BC, list<SObject> scope){
// Create a new schedule using System.schedule for the above AccountScheduler class
global void finish(Database.BatchableContext BC){
  Datetime dt =;
  String schedule='0 0 0-23 * * ?';
  String name = 'New job name: ' +; 
  AccountScheduler nextBatchJob = AccountScheduler();
  System.schedule(name,schedule, nextBatchJob);


  1. AccountScheduler will run at whatever time you select via Setup (you can select any recurring time, its the preferred start time that's important)
  2. AccountScheduler will abort the job in step 1.
  3. It will run AccountBatch
  4. AccountBatch in the finish method will schedule AccountScheduler to run 1 hour later.
Steps 2 - 4 will go into an infinite loop.



promote demote