Technically, Salesforce has no hard limit on the number of triggers per object — you can create as many as your org’s metadata allows. Practically, the only correct answer in 2026 is one trigger per object. This is the universally accepted best practice and the answer interviewers want to hear.
Why “one trigger per object”
When multiple triggers exist on the same object, Salesforce does not guarantee the order they execute in. The order can change between deployments, between sandbox refreshes, and even between releases of the platform. A subtle dependency — “trigger A must run before trigger B” — that works in your sandbox can silently break in production.
Other reasons:
- A single recursion guard. With one trigger, one static boolean (or
Set<Id>) governs the whole lifecycle. Multiple triggers each need their own — and they can re-fire each other. - A single bypass switch. Production support sometimes needs to disable a trigger fast. One file, one flag.
- Predictable testing. Test coverage targets one entry point per object, not three.
- Predictable code review. Reviewers always know where to find the entry point.
- Easier ordering. When the handler routes by
Trigger.operationType, you control the exact sequence of operations inside one file.
What the reference shape looks like
trigger AccountTrigger on Account (
before insert, before update, before delete,
after insert, after update, after delete, after undelete
) {
new AccountTriggerHandler().run();
}
public with sharing class AccountTriggerHandler {
public void run() {
switch on Trigger.operationType {
when BEFORE_INSERT { /* setDefaults, validate */ }
when BEFORE_UPDATE { /* deltas, derived fields */ }
when AFTER_INSERT { /* create children */ }
when AFTER_UPDATE { /* roll up to parents */ }
when AFTER_DELETE { /* cleanup */ }
when AFTER_UNDELETE { /* re-derive state */ }
}
}
}
All seven contexts route through one file. Order is whatever you code inside the handler.
When you might see multiple triggers anyway
In real orgs, you’ll inherit codebases with AccountTrigger1, AccountTriggerLegacy, AccountTrigger_Old because nobody refactored. The right move is to consolidate them — copy the logic into a single handler, delete the redundant trigger files, and add tests that prove behavior is preserved.
Managed packages also install their own triggers, and you can’t merge those into your file. That’s fine: the rule is one trigger per object per package namespace.
The technical hard limits
For completeness — there are governor-style limits on triggers, but they’re not “how many triggers per object”:
| Limit | Value |
|---|---|
| Maximum trigger depth (recursive re-entry) | 16 |
| Max code size per trigger | 1 MB |
| Max chained trigger executions (workflow re-fires) | 5 levels |
Common interview follow-ups
- Can two triggers on the same object share data? — Only via static variables or the database. There’s no shared “context bag.”
- Is “one trigger per object” enforced by Salesforce? — No. It’s a best practice, not a platform rule.
- What if I have a managed package trigger I can’t change? — That’s an exception. Your code goes in your trigger; the managed package’s goes in theirs. They run in undefined order — design accordingly.
Verified against: Apex Developer Guide — Triggers and Best Practices, Execution Governors and Limits. Last reviewed 2026-05-17.