Apex CPU time limit

Salesforce imposes a limit on the CPU usage that can be consumed in a given transaction, which is approximately

TimeoutType
10 secondsSynchronous Apex
60 secondsAsynchronous Apex
  • Note: these are hard-limits, can't be increased!

  • An Apex CPU Timeout Exception effectively means that Apex Code (or process builder/ flows or both) is attempting to execute and is exceeding the cpu time limit.

  • Any DML executions contained within the transaction will be rolled back if the limit is hit.

  • We only count events that require application server CPU use

Not counted

  • Things beyond your control as a programmer are not included
    • Time spent in the database retrieving records won't count.
    • Time spent waiting for a callout to return is also not included.
    • Code compilation time isn't counted.

Counted

  • All Apex code
  • Library functions exposed in Apex
  • Workflow execution
  • If DML in your code encounters a validation rule with a formula, we'll count the time spent evaluating that formula.
  • CPU time is calculated for all executions on the Salesforce application servers occurring in one Apex transaction

Suggestions

  • Using Map based query
    • Using Map query saves CPU time
//Fetching all account in map
Map<id,account> aMap = new Map<id,account>([Select Id,Name from Account limit 50000]);

  • Explore if your business allows you to do the operation asynchronously
    • If there is a chance to make code execute in @future ,this will break the context and also the CPU time out limit for asynchronous process is 60 seconds (6 times of synchronous process)
  • Aggregate SOQL usage
    • Since the database time is not calculated in CPU time it is always better to explore the usage of aggregate SOQL for your business use case .

    • Say you want a summation of field value of some records. If you use normal for loop to get these, it is obvious you have spent CPU time there. Instead, try to push your calculation using SUM,AVG aggregate functions at the database layer itself. By doing this you have reduced CPU time and have pushed the process on database layer itself. Explore options to group by or create some sort of filtering at database layer. Push your calculations at database layer to reduce chances of hitting CPU time out issue.

  • Only take necessary data and run a loop
    • It is essential to filter only specific data while doing a for on a list of records. Too much looping will increase CPU time. The same was true when we had number of script statements limit

Resolution

ItemResolution
Process BuilderWhere viable, convert Process Builder processes to Apex Triggers using an asynchronous approach if possible.
Custom CodeIf you have custom code (i.e. trigger) you will need to contact your developer or responsible organization to refactor your current custom solutions to ensure you do not exceed the CPU time limit.
Batch ProcessingIf you are inserting or updating a large number of records, try reducing the batch size.
Async ApexUse @future calls and asynchronous processing to move non-critical business logic out of triggers and/or Process Builder processes.
Best PracticesConsider Salesforce best practices for Triggers and Bulk Requests
Managed Package involvementIf code from a managed package (i.e. Rollup Helper) is taking part in a transaction such as Posting a Billing you will need to contact the authors of that package.

  • Check for unexpected situation where trigger logic is executed multiple times
  • Check for nested loops in Apex code

Using Developer console to view timeline

  • Switching the perspective and using timeline
  • Timeline shows how the items (Apex, Flows, ...) are executed in sequence and how much time each of them consumes.

dc 1

dc 1

dc 1

dc 1

dc 1

References