08 May Salesforce Coding II: Too Many Triggers?
When was the last time you took stock of the custom code in your Salesforce org? If it’s been a while, now might be the time to check on your triggers. Older Salesforce orgs may have evolved to include more than one trigger per object. This can cause unpredictable behavior, which is never a good thing. Does your Salesforce org have too many Apex triggers?
How did we get here?
It happens sometimes. A request comes in for a new data automation feature in a Salesforce org. You’re in the middle of a different initiative, but you take a moment to fulfill the Salesforce coding request. Write a small trigger and a test class, deploy, and you’re done. The requesting user is happy.
Until, that is, errors from exceeding governor limits start to crop up. Or reports of data anomalies start trickling in. It may take some time before anything unusual happens, so by that time you’ve forgotten about that little trigger. You may even have repeated the process for a couple of other change requests. The frustration builds, both for you and for your team.
Take a look at your Apex code base. Do any of your objects have more than one active trigger for the same event? If so, fix that! Combine the triggers because you have no direct control over which one executes first.
How and when do Apex triggers execute?
Let’s back up for a moment to review where triggers fit into the overall scheme of things. According to the Apex developer guide, “Apex triggers enable you to perform custom actions before or after changes to Salesforce records, such as insertions, updates, or deletions.”
Triggers are generally classified as “before” or “after” triggers. As you might expect from the name, “before” triggers execute before the data change is saved to the database, and “after” triggers execute after the change is saved but before it’s committed. A data change may be an insert, upsert, update, delete, merge, or undelete action.
Which operation happens first?
In general, the server performs basic data validation first. The details depend on whether a user changed the record directly or an Apex application/API call changed it. Then it executes the “before” triggers and re-runs most of the system validations, checks duplicate rules, saves the record, and executes the “after” triggers.
Assignment rules, auto-responses, workflow rules, processes, and other rules all come after the “after” triggers, but some of those automations like workflow field updates will fire “before update” and “after update” triggers one more time. (Is your head spinning yet? It’s a lot of steps, but it is systematic, I promise.)
The real kicker here is this:
“The order of execution isn’t guaranteed when having multiple triggers for the same object due to the same event. For example, if you have two before insert triggers for Case, and a new Case record is inserted that fires the two triggers, the order in which these triggers fire isn’t guaranteed.” –Apex Developer Guide, “Triggers and Order of Execution”
If you can’t control the order of execution, then you may see different results when the triggers execute in different order. Of course, this depends on what your triggers do and what other data relationships your org includes. Nevertheless, unpredictable code is bad code.
How do governor limits apply?
Another reason that Salesforce coding best practices include using one trigger per object on the same action relates to governor limits. Just because each individual trigger stays well within the limit of 100 SOQL queries doesn’t mean there won’t be over-limit exceptions. Those governor limits apply to all code that is processed. If a trigger causes a field update that activates a workflow field update that fires another trigger, the whole combination counts toward the limit.
This isn’t the place to delve into debug logs or the Limits class. There are tools that can help you manage resource usage in your Salesforce coding; if you’re interested in more details, check out the documentation.
Why is it better to use a single trigger per object?
OK, it doesn’t absolutely have to be one trigger per object as long as you have only one trigger per object for the same event. That said, it’s much easier to manage your code base as a whole if there’s one trigger per object.
As discussed in 3 Considerations for Salesforce Coding, that doesn’t mean you need huge, monolithic trigger classes. On the contrary, you need to organize triggers and helper classes into a coherent architecture. Place the handler methods into helper classes. There’s a great discussion of trigger frameworks and best practices in the Salesforce Technical Library.
Over time, some Salesforce orgs can evolve to have multiple triggers on the same object and event. This is not in line with best Salesforce coding practices and can lead to governor limit exceptions and/or unpredictable data results. Too many Apex triggers can cause a lot of trouble. For best results, curate your code so that there’s only one trigger per object for the same event.
Click here to learn more about Salesforce development.