Skip to content
Skip to content
SalesforceFox

SalesforceFox

Easy way Learning & Exploring Salesforce !

  • Home
  • All Blogs
  • How To
  • Tips & Tricks
  • Salesforce Quiz
  • Resources
  • About
Create Dynamic Job Scheduling Framework in Salesforce

Create a Dynamic Job Scheduling Framework in Salesforce to Manage multiple Scheduled Jobs

Piyush LakhaniJune 13, 2025June 13, 2025

In Salesforce, scheduling jobs at specific times is essential for automating repetitive tasks. However, static schedules can become cumbersome when managing multiple jobs with varying intervals. Static cron expressions also lack the flexibility needed for dynamic business needs, and Salesforce limits organizations to just 100 active scheduled jobs. To overcome these constraints, Let’s explore how to create a Dynamic Job Scheduling Framework in Salesforce, to manage multiple scheduled jobs.

In this blog, we’ll dive deep into the Dynamic Job Scheduling Framework: what it is, how it works, and why it’s a needed for automating scheduled jobs in a dynamic environment.

Table of Contents
[Open][Close]
  • Why Dynamic Job Scheduling Framework ?
  • Salesforce Scheduling Basics
  • Key elements of this Framework
  • A step-by-step guide to Create this Framework
    • Dynamic Job Scheduling framework – Overview
    • Steps to Create Dynamic Job Scheduling Framework
  • Example Use Case
  • Consideration
  • Summary

Why Dynamic Job Scheduling Framework ?

Traditionally, in Salesforce, Scheduling multiple tasks to run at specific times, dates, or days requires creating individual scheduled jobs for each task in the Setup menu. While this works for simple automation, it quickly becomes inflexible when business logic changes. If you need to modify an existing scheduled job class, you must delete the current job from Setup before creating a new one — a non-dynamic and time-consuming process.

Another limitation is Salesforce’s 100-scheduled-job limit, which restricts the number of active jobs you can have. For organizations that require more complex scheduling or have a growing list of tasks, this can be a significant bottleneck.

The Dynamic Job Scheduling Framework solves these problems. By setting up only one master scheduled job in Setup, all other jobs are defined and managed in custom metadata.

What Dynamic Job Scheduling Framework can do :

  • Overcome the 100-job limit, as you can define and manage more jobs in custom metadata.
  • Modify scheduling logic on-the-fly without having to delete or recreate scheduled jobs.
  • Add or remove tasks as needed without worrying about Salesforce’s scheduled job limit.
  • Maintain a centralized configuration to control all scheduled jobs, reducing the complexity of managing multiple jobs.

With this framework, you gain flexibility, scalability, and easier management of your scheduled jobs in Salesforce, ensuring that your automation can evolve as your business needs change.

Salesforce Scheduling Basics

Salesforce uses the Schedulable interface to schedule jobs. Once apex class implements this Schedulable interface, it can be executed at specific intervals (hourly, daily, weekly, etc.).

Check this basic example:

public class MySchedulableClass implements Schedulable {
    public void execute(SchedulableContext sc) {
        // your logic here
    }
}

Now in Salesforce, you can schedule a job in Anonymous Window:

String cronExp = '0 0 0 * * ?';  // runs daily at midnight
MySchedulableClass job = new MySchedulableClass();
System.schedule('My Job1', cronExp, job);

You can also do same from Set up, search for scheduled Job, Click on Schedule Apex and provide same details as above and Click Save.
However, when you need flexibility and customization, it’s better to rely on Dynamic Job Scheduling framework

Key elements of this Framework

The Dynamic Job Scheduling Framework leverages One Master Scheduled Job which are scheduled to run every hour and Custom Metadata to store rest of all the job schedules dynamically.

  • Custom Metadata Configuration: This Custom metadata records are used to store details about which schedulable class to run & what time, day, week and month.
  • Master Apex Scheduler: This Master Apex Scheduler which is scheduled to run every hour, get all custom metadata records, loop through each metadata record and  evaluates whether the current time, day, or month matches the conditions in the metadata and execute schedulable class from that record.
  • Schedulable Classes: All your Schedulable classes along with when it should run (what time, day, month) should be stored in custom metadata we configured above.
  • Error Handling: If a scheduled job fails to meet the conditions or throws an error, proper error handling mechanisms ensure the framework doesn’t crash and provides meaningful logs.

A step-by-step guide to Create this Framework

Dynamic Job Scheduling framework – Overview

Dynamic Job Scheduling FrameWork FlowChart

Steps to Create Dynamic Job Scheduling Framework

Step-1 : Create Custom Metadata

First, create a Custom Metadata Type called Dynamic_Scheduled_Class_Config__mdt. This metadata type will store:

  • The Schedulable Class API Name to execute
  • The Month, Day of the Week, Day of the Month, and Hour to run the job

Therefore, Let’s create Dynamic Scheduled Class Config‘s Custom Fields as shown below :

Custom Field label
Custom Field API
Field Type
Picklist Values
Default picklist Value
Required Field ?
Schedulable Class API Name
Schedulable_Class_API_Name__c
Text
–
–
Yes
What Day of Month to Execute
What_Day_of_Month_to_Execute__c
Picklist
No Value
1 to 31
No Value
Yes
What Day of Week To Execute
What_Day_of_Week_to_Execute__c
Picklist
No Value
MON,TUE,WED,
THU,FRI,SAT,SUN
No Value
Yes
What Hour to Execute (24 hrs)
What_Hour_To_Execute__c
Picklist
1 to 24
–
Yes
What Month To Execute
What_Month_To_execute__c
Picklist
No Value
JAN,FEB,MAR,APR,
MAY,JUN,JUL,AUG
SEPT,OCT,NOV,DEC
No Value
Yes
Is Active
Is_Active__c
Checkbox
–
–
No

Step-2 : Create Master Scheduler Class :- DynamicJobSchedulingManager

public without sharing class DynamicJobSchedulingManager implements Schedulable{

    public void execute(SchedulableContext sc) {
  
        //get all ScheduledClassConfig Custom Metadata records
        List<Dynamic_Scheduled_Class_Config__mdt> schClassList = [
                            SELECT Id, DeveloperName, Schedulable_Class_API_Name__c,
                            What_Month_To_execute__c, What_Day_of_Month_to_Execute__c,
                            What_Day_To_Execute__c, What_Hour_To_Execute__c
                            from Dynamic_Scheduled_Class_Config__mdt 
                            WHERE Is_Active__c = true];
                                                                        
        checkToRunSchedulersOneByOne(schClassList, sc);                                             
    }
    
    private void checkToRunSchedulersOneByOne(List<Dynamic_Scheduled_Class_Config__mdt> schClassList, SchedulableContext sc){
        
        for (Dynamic_Scheduled_Class_Config__mdt scheduledClassDetail : schClassList) {
            
            if (RunThisSchedulerNow(scheduledClassDetail)) {
                try {  
                    Type targetClass = Type.forName(scheduledClassDetail.Schedulable_Class_API_Name__c);
                    if (targetClass != null) { 
                        Object classInstance = targetClass.newInstance();  // Create an instance of the class 
                        // Check if the class has the Schedulable interface  
                        if (classInstance instanceof Schedulable) {  
                            Schedulable schedulableInstance = (Schedulable) classInstance; 
                            schedulableInstance.execute(sc);
                        }
                        else { 
                            system.debug('A class ' + scheduledClassDetail.Schedulable_Class_API_Name__c + ' doesnt implement Schedulable interface');
                        }
                    } else {
                        system.debug('A class ' + scheduledClassDetail.Schedulable_Class_API_Name__c + ' doesnt exist');
                    }
                } catch (Exception ex) {
                    system.debug('Error Message: ' + ex.getMessage());  
                }
            }
            else{
                system.debug('No scheduled class to run at this time'); 
            }
      }
    }
    
    private Boolean RunThisSchedulerNow(Dynamic_Scheduled_Class_Config__mdt rec){
        
        Boolean checkToRunSchedulableClass = false;
        //Map to convert month number to month name
        Map<Integer, string> mapMonths = new Map<Integer, string>{
    					1=> 'JAN',2=> 'FEB',3=> 'MAR',4=> 'APR',5=> 'MAY',6=> 'JUN',
    					7=> 'JUL',8=> 'AUG',9=> 'SEP',10=> 'OCT',11=> 'NOV',12=> 'DEC'};

        //Get current hour, month, day of month and day of week
        Integer currentHour = System.now().hour();
        String currentMonth = mapMonths.get(System.now().month());
        Integer dayOfMonth = System.now().day();
        String dayofWeek = System.now().format('EEE');
        String dayToday = dayofWeek.toUpperCase();
        
        String runOnMonth = String.valueOf(rec.What_Month_To_execute__c);
        String runOnDayofWeek = String.valueOf(rec.What_Day_To_Execute__c);
        Integer runOnDayofMonth = rec.What_Day_of_Month_to_Execute__c !='NoValue' ? Integer.valueOf(rec.What_Day_of_Month_to_Execute__c):32;
        Integer runAtHour = Integer.valueOf(rec.What_Hour_To_Execute__c);
        
        checkToRunSchedulableClass = ((runOnDayofWeek == dayToday &&  runAtHour == currentHour) || 
                                      (runOnDayofWeek == dayToday && runOnMonth == currentMonth && runAtHour == currentHour) ||
                                      (runOnMonth == currentMonth && runOnDayofMonth == dayOfMonth && runAtHour == currentHour) ); 

        return checkToRunSchedulableClass;
    } 
  }

Let’s break down this code into pieces:

  1. DynamicJobSchedulingManager class implements Schedulable interface so we can schedule it to every hour via CRON [ 0 0 * * * ? ]. check out here How to build Cron in Salesforce
  2. First of All, it will fetch only Active custom metadata records of Dynamic_Scheduled_Class_Config. each of these record stores a schedulable class and when to run it.
  3. Once we have all Active metadata records, method checkToRunSchedulersOneByOne(...) will be called,
    • Inside this method, For each record, Call RunThisSchedulerNow(...) to decide if scheduler class should run Now.
    • If yes, Loads the class dynamically using Type.forName(…) & ensure it implements Schedulable.
    • If anything fails (e.g., class not found, class doesn’t implement Schedulable), it logs a debug message.
  4. Inside RunThisSchedulerNow(...)
    • It will decide whether a job should be run now based on
      • Current month, day of the month, day of the week, and hour.
      • Compare them with metadata values : WhatMonth, WhatDay …
    • It returns true if any of the following match:
      • Day of week & hour match [ e.g. 1 AM every Sunday]
      • Day of week, month, & hour match [ e.g. 6 PM every Sunday in March, April]
      • Day of month, month & hour match. [ e.g. 5 AM on 15th of every month]

Example Use Case

Business Scenario :

You’re running an e-commerce Platform where certain jobs needs to run on specific days of month/week or at different time based on several factors (like, weekly inventory updates, monthly financial reports)

Here are some frequent tasks :

  • SendWeeklySalesReportJob : it sends weekly reports every week on Monday 7 AM.
  • UpdateQuarterlyLoyaltyDiscountsJob : Update Discount for loyal customer quarterly .

You have decide to use Dynamic Job Scheduling Framework to handle to multiple scheduled tasks you have and its frequency can also be changed any time.

Here is how it will work :

  1. First task this to schedule our Master Scheduler class : DynamicJobSchedulingManager to run at every hour. So that every hour, this master scheduler check if current time matches any configured scheduler in custom metadata
  2. Now, we need to Set up metadata records Dynamic Scheduled Class Config to define specific Jobs we have above.
    • Go to this custom metadata & create new records as follow
Creating Dynamic Scheduled Class Meta data Config Record

All Metadata Records for Scheduled Class Config :

All Dynamic Scheduled Job Config Meta Data Records

3. Now Once you created metadata records for all scheduled Jobs, Our Master Scheduler class wakes up every hour and query this metadata & check if current time matches any specified time from metadata, it will execute that scheduler class right away.

Consideration

  • This Frameworks’s Master Scheduler is running at every hour, Currently Salesforce Cron expression does not support every minute scenario, Therefore, this framework does not work in case your need to run your task at certain minutes of hour.
  • This framework is best suited for scenarios with complex or frequently changing scheduled tasks, where managing multiple schedulable classes manually becomes inefficient. It offers flexibility and central control through metadata, reducing the need for frequent code changes. For simple or static schedules, native Salesforce scheduling may be more straightforward.

Summary

  • Building a Dynamic Scheduler Framework in Salesforce is a powerful way to automate and schedule jobs based on flexible, customizable configurations. This approach offers increased maintainability, scalability, and flexibility for organizations with complex scheduling needs.
  • By leveraging Custom Metadata, you can make job scheduling a breeze and tailor it according to your specific needs !
Share this Now :

Related Posts:

  • How to use Cron Expressions in Salesforce
    How to use Cron Expressions in Salesforce - Discover…
  • How to Secure Your Salesforce Org
    How to Secure Your Salesforce Org: First Steps…
  • User Access Policy in Salesforce : The Smartest way to Automate User Management Jobs
    User Access Policy in Salesforce : The Smartest way…
  • Send Automatic Reminder Emails To Inactive Users
    Send Automatic Reminder Emails to Inactive Users in…
Apex, Automation, Best Practices, Development, Scheduled Jobs

Post navigation

Previous: How to use Flow Approval Process In Salesforce ?
Next: How to Zip & Unzip files Natively in Salesforce: Use This Ready-to-Use ZIP Utility

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Get Weekly Salesforce Quiz

Categories

  • Admin (8)
  • Apex (6)
  • Automation (7)
  • Best Practices (6)
  • Flow (5)
  • LWC (4)
  • Security (1)
  • SOQL (1)
  • Trigger (1)
  • Uncategorized (1)

Recent Posts

  • User Access Policy in Salesforce : The Smartest way to Automate User Management Jobs
  • Display Apex-Defined Collection Data directly into Screen Flow Data Table
  • How to Secure Your Salesforce Org: First Steps Against Cyber Attacks and Social Engineering
  • Make Salesforce Screen flows more Interactive with Toast Messages
  • How to Zip & Unzip files Natively in Salesforce: Use This Ready-to-Use ZIP Utility

Tags

Admin Apex Aura Component Automation Best Practices Development Email Alerts Flow Flow Approval Process How To Lightning Experience LWC Reports Scheduled Jobs Security SOQL Tips Trigger User Management

Archives

  • November 2025 (1)
  • October 2025 (1)
  • August 2025 (1)
  • July 2025 (1)
  • June 2025 (2)
  • May 2025 (1)
  • April 2025 (2)
  • March 2025 (2)
  • January 2025 (2)
  • December 2024 (1)
  • October 2024 (1)
  • September 2024 (1)
  • August 2024 (1)
  • June 2024 (1)
  • April 2024 (1)
  • March 2024 (1)
  • October 2023 (1)
  • Linkedin
  • Youtube
  • Privacy Policy
  • Terms of Use
  • Contact
Theme: BlockWP by Candid Themes.
© 2023-2026 | SalesforceFox.com