Trigger Frameworks & Best Practices
Bulkification (Most Important Rule)
What Is Bulkification?
Bulkification means writing trigger logic that works correctly when one record or many records are processed together.
Simple Explanation
Salesforce can save 200 records at once.
Your trigger must handle all of them in one go.
Real-Life Example
Processing payroll for 1 employee vs 200 employees — the logic should still work.
❌ Non-Bulkified Trigger (Bad)
trigger BadTrigger on Account (before insert) {
for (Account acc : Trigger.new) {
Contact c = [SELECT Id FROM Contact WHERE AccountId = :acc.Id LIMIT 1];
}
}
✅ Bulkified Trigger (Good)
Set<Id> accountIds = new Set<Id>();
for (Account acc : Trigger.new) {
accountIds.add(acc.Id);
}
Map<Id, Contact> contactMap = new Map<Id, Contact>(
[SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]
);
Gist (Quick Revision)
Always assume multiple records—never write trigger logic for just one.
2. Trigger Handler Frameworks
What Is a Trigger Handler?
A trigger handler moves logic out of the trigger into a class.
Simple Explanation
Trigger = doorbell
Handler = person doing the work
Why Use a Handler Framework?
-
Cleaner triggers
-
Reusable logic
-
Easier testing
-
Better maintenance
Basic Trigger + Handler Example
Trigger
trigger AccountTrigger on Account (before insert, after update) {
AccountTriggerHandler.handle(Trigger.new, Trigger.oldMap);
}
Handler Class
public class AccountTriggerHandler {
public static void handle(List<Account> newList, Map<Id, Account> oldMap) {
// business logic here
}
}
Gist (Quick Revision)
Triggers should call handlers, not contain logic.
3. Recursion Control
What Is Recursion in Triggers?
Recursion happens when a trigger updates the same object, causing itself to run again.
Simple Explanation
Like two mirrors facing each other—never-ending reflection.
Real-Life Example
Updating an Account inside an Account trigger → trigger fires again.
Safe Recursion Control Pattern
public class TriggerHelper {
public static Boolean isFirstRun = true;
}
if (TriggerHelper.isFirstRun) {
TriggerHelper.isFirstRun = false;
// logic here
}
Why This Matters
-
Prevents infinite loops
-
Avoids CPU limit errors
-
Ensures predictable behavior
Gist (Quick Revision)
Always protect triggers from running repeatedly.
4. Trigger Anti-Patterns (What NOT to Do)
❌ Anti-Pattern 1: SOQL Inside Loops
-
Causes governor limit issues
❌ Anti-Pattern 2: DML Inside Loops
-
Breaks bulk operations
❌ Anti-Pattern 3: Business Logic in Trigger
-
Hard to test
-
Hard to maintain
❌ Anti-Pattern 4: Ignoring Before vs After
-
Leads to wrong data behavior
Best Practice Summary
✅ Bulkify everything
✅ Use handler frameworks
✅ Control recursion
✅ Keep triggers thin
Gist (Quick Revision)
Good triggers are bulk-safe, clean, and controlled.
