Loading

Code more efficiently to avoid 'Apex CPU time limit exceeded'

Publiseringsdato: Oct 13, 2022
Beskrivelse
Salesforce has a timeout limit for transactions based on CPU usage. If transactions consume too much CPU time, they will be shut down as a long-running transaction.
Løsning

We only count events that require application server CPU use. There are some things that use the app server CPU that we don't count. Things beyond your control as a programmer are not included. For example, the time spent in the database retrieving records won't count. Time spent waiting for a callout to return is also not included. You don’t control when your code needs compilation, so that time isn't counted.
 

We'll count almost everything else that happens on the app server, including declarative actions. 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—for the executing Apex code, and any processes that are called from this code, such as package code and workflows. CPU time is private for a transaction and is isolated from other transactions. Operations that don’t consume application server CPU time aren’t counted toward CPU time.
 

What is counted

  • All Apex code
  • Library functions exposed in Apex
  • Workflow execution

What is not counted

Best practices to reduce CPU timeout

You can refer to Apex Code Best Practices  to help reduce the CPU timeout. We'll go over some of the suggestions below. 

Using Map based query

List<Account> lstacc=[Select Id from Account limit 10000];
Set<Id> setIds=new Set<Id>();
for(Account a:lstacc){ //More CPU time for sure due to looping
setIds.add(a.id);
}

//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]);

//Creating list of accounts
List<account> accList = aMap.values() ;

//Creating set of ids

Set<id> accIds = aMap.keySet() ;

Explore if your business allows you to do the operation asynchronously

In some cases business process may not be real time. 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 60seconds(6X of synchronous process). Consider this if you're at risk of hitting the limit.

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.

 

Knowledge-artikkelnummer

000387833

 
Laster
Salesforce Help | Article