What is a Apex CPU timeout?
For every transaction like updating an account or creating a new contact, automation's that run in the background get 10 seconds. If your automation's take more than 10 seconds that leads to a Apex CPU timeout exception and the operations is aborted. Note that in most orgs you get an additional 5 seconds as a grace period, however generally you should strive to keep your automation's down at 10 seconds.
What causes CPU timeout?
It's not just apex code that causes a Apex CPU timeout exception. Flows, process builders and apex triggers equally contribute towards this exception. Bad design and implementation of these automation's lead to this exception.
Where do i start?
Firstly, you would want to figure out where these exceptions are happening and how many of these are happening. Turn on apex exception notifications so you get notified when timeouts happen by a apex trigger. This will give you an exception email for every single exception, create a rule in your mailbox and store these in a specific folder. You could create a filter with this keyword to only filter out timeout exception emails (Apex CPU time limit exceeded)
Event Monitoring
Event monitoring is a add-on from Salesforce for additional price, if you have this you can make use of this table. You can export the daily logs using the ELF browser or use Event Monitoring Analytics App
ApexUnexpectedException - Run a filter on this table where Exception Message contains (Apex CPU time limit exceeded)
How to Debug ?
The exception message contains the stack trace, which gives you the Apex Class and the apex method that is causing this exception. In this example you see the apex class causing this.
How to reduce CPU time?
Once you have narrowed down to the apex class or trigger causing this, look for bad coding practices. Some of these would be
- No multiple apex triggers on the same object
- No multiple process builders on the same object. If you have many move them to Flow or Apex trigger.
- If Apex trigger does not implement a framework, consider implementing it. This might take considerable effort but is a good investment for the long term.
- No SOQL inside a FOR loop
- FAST Field Updates, and beforeupdate / before insert methods are used appropriately for updates to the same object
- Check for recursion and stop it happening.
- Consider moving some transactions to anynchronous mode, FUTURE methods. Asynchronous triggers, Time delayed flows are some examples.
- Consider usign Platform Events to reduce CPU time and split out the automation into its own transaction