Have you ever received the message “Apex CPU time limit exceeded” after writing and testing some code? The first time I received this message I wondered what a CPU has to do with my code in the cloud?!
After some research, I found out that the Salesforce platform imposes a CPU usage governor limit to any given execution context, which is approximately 10 seconds. It means that Apex Code, declarative tools or a combination in a transaction, must not exceed a ~10-second limit.
The CPU time error is contained within Salesforce Governor Limits. Let’s dive into the specifics of this, why it’s important, and how we debug it…
5 Things to Know
First of all, what are Salesforce governor limits? Due to the multi-tenant nature of the Salesforce platform, different governor limits are introduced to ensure that no customer can monopolize the shared resources. You can refer to this article to study more on the Salesforce multi-tenancy topic. These are the 5 key points to know…
- The error also involves declarative tools. It is calculated for the executing Apex code and any processes that are called from this code, such as package code, workflows, process builders and flows. Thus it is not merely for Apex as the name entitles.
- It is shared with certified managed packages. The certified managed package is a package that has passed the security review for AppExchange. It has its own set of limits for most per-transaction limits. However, Apex CPU Time Limit is an exception.
- It is non-negotiable. This means we cannot increase the 10-second threshold by tweaking settings, buying more allocations from Salesforce or work around it by other means. It is an absolute hard limit.
- It shuts down the execution immediately. It is a full stop.
- It rolls back all database transactions. For example, you might have done multiple DMLs successfully in the transaction. These DMLs are reverted when this limit hits.
How to Tackle the Apex CPU Time Limit
1. Be aware
The first step is to simply be aware when it happens.
In some scenarios, it’s easy to spot it. For instance, you see this error popping up on a VisualForce page or you expected a calculated field value that didn’t arrive. Here you have the clue that a CPU Time Limit exception has occurred.
In other scenarios when the code execution runs merely in the background, it’s much more difficult to catch that it has happened. For instance, you might have a scheduled batchable running. In the try-catch code block of this batchable, when the code encounters an exception, you could write a message into a custom LogInfo__c object and also send out an email notification.
However, this solution doesn’t handle the Apex CPU Time Limit. When the Apex CPU Time Limit arrives, any message, in the current transaction, that has been previously written into LogInfo__c rolls back, and the email notification logic doesn’t execute at all. In order to be aware that the Apex CPU Time Limit has occurred, you need to enable and observe the live Debug Log.
2. Find out what consumes the most CPU Time
Let’s assume that we have enabled the live Debug Log and witnessed the Apex CPU Time Limit exception in the Account trigger. Now, we are aware. A good first step.
The second step is to find out what consumes most of the CPU time. However, like the screenshot below, the debug log contains an excessive amount of information. We would like to only know what actions consume how much CPU time. Let’s switch to Analysis Perspective in the Developer Console.
Select Debug on the top menu -> Switch Perspective -> Analysis (Predefined)
Choose Timeline -> Scale (Choose the one fits you).
On this timeline view above, we can now see that Apex, Workflow, and Database actions are executed in sequence and how much time each of them consumes.
Alternative third-party tools are also available for log visualization, such as the SFDC Explorer tool. The downside of this tool is that it works only on Windows.
From this step on, we can dig into the details of the parts that consume too much CPU time.
3. Common Reasons Encountering the Apex CPU Time Limit
One of the common reasons we hit the CPU limit is that the trigger logic enters unexpectedly multiple times. Trigger logic finishes first, workflow follows to update the record which then causes the trigger logic to re-enter.
Another reason is the trigger custom code logic itself. Is your Apex code performant? For example, nested loops can be very slow when processing a large volume of records.
The last but not least reason is the code in the managed packages. This is, unfortunately, a BlackBox, if the code in a managed package consumes too much time, you need to reach out to the vendor for assistance.
In this article, we have gone through why the Apex CPU Limit is a special Salesforce governor limit you need to pay attention to, how to investigate and visualize the log information to locate the main CPU consuming parts, and what are the common reasons causing this error. I hope you now have more confidence in dealing with it!