• Working with Multiple 2GP Packages in a Single Namespace.
  • It's a big package(s). OEM environment so this is the core application used by clients on the salesforce platform and takes advantage of standard objects such as Accounts & Contacts as well as lots of custom objects).

Question: A colleague recently proposed implementing a rule of 'triggers for one object not creating or editing records of a different object'. Is this a good or bad principle architecturally? Why is this a good or a bad idea?

Example: On insert of a new contact it would not be able to automatically create a household account. Either the user does it manually via the UI or a batch job creates it.

Some previous experiences that are influencing this idea:

  • Long cascading chains of record triggers hitting limits or resulting in unexpected outcomes.
  • Complex to understand chain of events following apparent simple changes on one record.

Particularly interested in the thoughts/input of others working in the managed package rather than a single Org solution.

1 Answer 1


WARNING: At least partially opinion lead

I want to first set the scene.

A package can add value by providing automation for use on the subscriber org. This automation is typically the main value-add of such a package.

There are many different types of automation, initiated in various different ways and each with its own capabilities, pros and cons and built-in ability for subscribers to enable and disable them (or not).

For example, where a package has very specific constraints over input data you might like to apply specific validation. Use of a validation rule can be by-passed since it can be disabled by the subscriber admin, while this is not the case with a trigger-based validation since packaged triggers cannot be disabled.

Now to turn to your question: should triggers create or modify (un)related objects?

For me, there are two aspects: business and technical.

The business case could be such that your package's value-add means it is necessary to have such cross-object manipulation when record changes are applied (by the user or other automations).

From a technical perspective you may need to have the equivalent of rollups but where there is no master detail relationship (NB: here you could use DLRS). Alternatively, in order to realise reports or data consistency, such automation may be essential.

Considering the argument for avoiding trigger-based cross-object dependency, there are valid points raised in your question. However, if you exclude such automation you may seriously reduce the value-add from your package, putting the onus and effort onto users who may not understand why they are to manually update other records or who may forget to do so, resulting in data inconsistency.

Remember that there are different types of automation; instead of using a trigger you might use a before or after save record flow. Clearly, in the big picture this can still suffer the negatives your colleague pointed out.

That said, there are various ways you can approach avoiding many technical constraints, such as governor limits, if not the removal of complexity. One example is to use a so-called adaptive batch and another the slightly simpler governor friendly async processing from triggers. Both of these approaches process records in a single-threaded manner, selecting just those that still need processing, and can be used to apply cross-object manipulation. They are initiated through a simple platform event that in turn is published through a trigger or flow that requires some processing to be performed based on the contextual record(s).

There are other solutions for this, perhaps based on queueables, though this can be more difficult to address in an async-efficient manner. Async limits need to be considered, as do batch execution constraints. This is why I ended up with the "governor friendly" approach, though this uses your hourly Platform Event limits (you can't get away from the governor!).

Finally, for me, understanding a full chain of events is best addressed with appropriate and up-to-date documentation that considers each step in isolation but where the reader can follow the flow straight-forwardly, a bit like those choose-your-own-ending story books.

In summary, it is my opinion that such a rule is generally a good idea (such chained triggers are too susceptible to governor limit issues, especially when a subscriber org admin adds their own automations to one of the objects involved), but does not stop you having a technical approach for cross-object manipulation that gives the same effect (albeit in an asynchronous manner), supported by relevant documentation to help developers and users alike understand the implications of what they do.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .