Batch Apex – First error: Apex CPU time limit exceeded

In this post, I would share my recent experience in fixing “CPU time limit” error in Batch apex and reason. When I encountered this error, initially thought that it would be easy to fix by following some of basic rules like :

  1. Remove unnecessary code and loops
  2. Efficient use of collections (Set, Hashmap or List)
  3. Avoid using loop within loop
  4. SOQL query should be indexable
  5. Avoid unnecessary re-initialization of variables
  6. Use Aggregated SOQL (as Database operations not counted in this limit, avoid arithmetic operations in Apex)
  7. Check how much time Workflow rules and process builders are taking
  8. Is there any manage package performing heavy operations in transaction

This piece of code was handed over to me from previous team, so I was not fully aware about full functionality and thought to check debug logs. To my surprise, how many times I tried to get a log, every attempt failed. I was thinking that problem could be in execute method however Batch Apex was failing with no debug logs. I tried all my tricks to get debug log with no success.  Batch Apex was using Query locator and it could fetch up to 50 millions of record and therefore overlooked start method.

Below pseudo code will give you some idea about Batch Apex structure and data volume.

global class SampleBatchApex_CPUError implements Database.Batchable<sObject> {

	String query = ' SELECT Field1, Field2, (SELECT Name, Identifier__c FROM childObject__r Where type=\'some value\') FROM Contact'; 
	
	global Database.QueryLocator start(Database.BatchableContext BC) { 
		return Database.getQueryLocator(query);
	}

	global void execute(Database.BatchableContext BC, List<Contact> contacts) { 
		//Some code about 100 lines
	}
	
	global void finish(Database.BatchableContext BC) {
		//Perform cleaning and start another Batch job
	}	
}

Data volume in full copy sandbox were like

  • Contact – 270k+
  • ChildObject__c – 270k+

Reason for CPU time out (in my case) – SubQuery

I tried SOQL Query Plan and run same query in Developer console and workbench, but it was not timing out. Still, gave one shot to idea that I had and tried to remove subquery from start method and queried again in execute method. And voilla…. it worked. So, subquery in SOQL was causing CPU time limit error and it was not even able to enter in execute method. I got lost because there were no debug logs. Instead of spending time on actual issue, I spent lot of time to figure out why debug log is not showing up.

Lessons learned

  1. If we are getting CPU time limit error (in my experience I have seen many), then avoid using sub-query, its costly and time consuming. Damn !!! I need to tell my colleagues of previous projects to check code for subquery, where they are getting CPU error.
  2. If batch apex error says “First error – some error” , that means error is in start method and don’t even try to hunt for execute method debug logs.

Posted

in

by

Tags:


Related Posts

Comments

11 responses to “Batch Apex – First error: Apex CPU time limit exceeded”

  1. Dushyant Sonwar Avatar
    Dushyant Sonwar

    Thanks for posting such a great article in detailed description 🙂

  2. danny Avatar
    danny

    Hi Jitendra,

    Would you be able to provide insight on 7 and 8?:
    Check how much time Workflow rules and process builders are taking
    Is there any manage package performing heavy operations in transaction

    How are you able to determine time consumed by Workflow Rules and Process Builders? How do you determine which managed packages are performing heavy transactional operations?

    Thank You,
    Danny

  3. SFDC!! Avatar

    hello Jithendra ,

    can you tell me how did you fix this part in start method and made it working . such that we can also know how to fix this issues .

    String query = ‘ SELECT Field1, Field2, (SELECT Name, Identifier__c FROM childObject__r Where type=\’some value\’) FROM Contact’;

  4. Balbhadra Karki Avatar

    I read somewhere that database operations do not count against CPU time and here we are talking about sub queries causing it. Could you pl elaborate on this?

    Are you talking about sub query results getting processed in some loop which is firing main query?

    1. Jitendra Avatar

      That’s good point Balbhadra. Time spent at Database level would not cause CPU time limit however I guess Querylocator was doing some processing ? I am really not sure. However, changing to subquery did resolved issue, that’s all I can say. More Info – https://help.salesforce.com/articleView?id=000232681&language=en_US&type=1

      1. Jeferson Spencer Chaves Avatar

        Thanks for the workaround Jitendara.
        But to be honest, this looks like a platform issue because there is no actual code that we, as platform users, run while the query locator is being processed before this control is sent back to the execute method.

  5. Neha Avatar
    Neha

    Hi Jitendra,

    I am facing same issue, and nested query is very heavy.
    Can you please help me out in it?

  6. Steph Avatar
    Steph

    Wow!, thank you so much, you save my life today 🙂

  7. Chetna Avatar
    Chetna

    Wow, This is awesome !!

  8. Vidhya Avatar
    Vidhya

    Thanks for this article. I’m facing a similar issue while querying Account and Opportunities and need suggestions to optimize.

    SELECT field1, field2, field3……. , (SELECT Id,Name FROM Opportunities where StageName != ‘Closed Won’ AND StageName != ‘Closed Lost’) FROM Account WHERE Date_field = datevalue AND …..

    The batch size is 50.

    of records returned by the above query only once a month(based on Date_field) is 400K+ : batch is failing in the start() itself.

    My question is:
    If the Opportunities subquery is removed in start(), do you then suggest to query for Opportunities in the execute() for each batch chunk?

  9. Vinod Avatar
    Vinod

    Faced same issue today, and resolved by moving the sub-query to execute method. Saved my day. Thanks!

Leave a Reply to NehaCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading