Lets say I have a scheduled class called clsTerminator, every day at '0 0 0 * * ?' it searches custom object PoliceDatabase__c for John Connor to delete these records.

Example class:

global class clsTerminator implements Schedulable {

     global void execute(SchedulableContext sc) {

     public void findJohnConnor() {
         List<PoliceDatabase__c> JohnConnerResults = [SELECT Id, SSN__c FROM PoliceDatabase__c WHERE FirstName__c = 'John' AND LastName__c = 'Connor'];
         if (JohnConnerResults.size() > 0) {
             for (PoliceDatabase__c jc : JohnConnerResults) {
                 clsTerminator.terminate(jc.Id, jc.SSN__c);

     public static void terminate(String johnId, String johnSSN) {
         Boolean T800 = [SELECT ProtectedFlag__c FROM ProtectionStatus__c WHERE SSN__c =:johnSSN].ProtectedFlag__c;
         if (!T800) {
             System.debug('John Conner SSN No. ' + johnSSN + ' has been terminated');
         else {
             System.debug('John Conner SSN No. ' + johnSSN + ' is a protected record');

Other than Execution Governors and Limits (lets assume that we would never get close to the limits) would there be any other reason to move methods findJohnConnor and terminate to another class that implements Database.Batchable?

  • You have a query in a loop, so some optimization would be required if you had more than 99 Johns to look at.
    – sfdcfox
    Nov 29, 2017 at 6:14

1 Answer 1


Assuming you had optimized code and would not exceed the governor limits, there is no reason to have a Batchable class. This is because Batchable and Schedulable have the same basic governor limits, in terms of CPU time, heap size, database activity, etc. In other words, the Schedulable class will always finish the overall objective faster than using a batchable.

By the way, you can always mix a batchable and schedulable into the same class. I find it easier to manage my batchable classes this way. The general pattern for doing this is outlined below.

global class clsTerminator implements Schedulable, Database.Batchable<SObject> {
  global void execute(SchedulableContext context) {
  global Database.QueryLocator start(Database.BatchableContext context) {
    return Database.getQueryLocator(...);
  global void execute(Database.BatchableContext context, SObject[] scope) {
  global void finish(Database.BatchableContext context) {
  • Thanks for the easy to understand explanation. (Understand about not having a query in a loop, just wrote that class as an example).
    – Y12K
    Nov 29, 2017 at 7:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .