Mastering the Most Common Apex Trigger Interview Questions
If you are prepping for a technical round, you know that Apex Trigger Interview Questions are basically guaranteed to come up. I’ve sat on both sides of the table, and honestly, interviewers don’t care if you can recite a textbook definition. They want to know if you are going to break their production org with a non-bulkified loop or a recursive nightmare. It is all about how you handle real-world logic when Flow just isn’t enough.
Look, the “when to use a trigger” conversation has changed. With the recent updates to Flow, we are using code less often for simple updates. But for complex cross-object logic or high-volume processing, triggers are still the gold standard. When you are answering Apex Trigger Interview Questions, you need to show that you understand not just how to write code, but where that code fits in the larger Salesforce ecosystem.
1. Before vs After Triggers: Which one and why?
This is usually the first thing they’ll ask. The short answer? Use a “Before” trigger if you are updating fields on the same record that fired the trigger. It is faster because it saves an extra DML step. Use an “After” trigger when you need the record Id (which doesn’t exist until the record hits the database) or when you need to update related records. Here is a simple look at how we split that logic:
trigger AccountTrigger on Account (before insert, after insert) {
if(Trigger.isBefore && Trigger.isInsert){
for(Account acc : Trigger.new){
// Modifying the record before it saves - no DML needed
acc.Description = 'New Account Verified';
}
}
if(Trigger.isAfter && Trigger.isInsert){
// We have the ID now, so we can do stuff with related records
System.debug('New Account Created with Id: ' + Trigger.new[0].Id);
}
}
Why Apex Trigger Interview Questions Focus on Real-World Scenarios
Interviewers love to trip you up with recursion. A recursive trigger happens when your code performs an update that fires the same trigger again, creating an infinite loop. I’ve seen this happen most often when an “After Update” trigger updates the same record. The standard fix is using a helper class with a static boolean flag to make sure the code only runs once per transaction.
public class TriggerHelper {
public static Boolean hasRun = false;
}
trigger ContactTrigger on Contact (after update) {
if(!TriggerHelper.hasRun) {
TriggerHelper.hasRun = true;
// Your logic here
}
}But here is a tip from my experience: be careful with static flags if you are dealing with large data sets where the trigger might fire in multiple chunks of 200 records. Sometimes you need a more specific way to track which records have been processed so you don’t skip valid logic.
2. The Golden Rule: Bulkification
If you put a SOQL query or a DML statement inside a for loop during a live coding challenge, the interview is probably over. You have to write code that handles 200 records at once. We use Sets to collect IDs and Maps to link related data. This is essential for managing large data volumes without hitting governor limits.
Set<Id> accIds = new Set<Id>();
for(Contact con : Trigger.new){
accIds.add(con.AccountId);
}
// Query once, outside the loop
Map<Id, Account> parentAccounts = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :accIds]);
for(Contact con : Trigger.new){
Account parent = parentAccounts.get(con.AccountId);
// Do your logic
}3. Handling Async Calls and Mixed DML
Sometimes a trigger needs to do something heavy, like calling an external API or processing a massive calculation. You can’t make a web service callout directly from a trigger; you have to use @future or Queueable Apex. This also helps you avoid the “Mixed DML” error, which happens when you try to update a User record (Setup object) and an Account (Non-Setup object) in the same transaction. If you’re worried about limits, check out this guide on staying under async limits.
Practical Tip: Always check if you are already in an asynchronous context before calling a @future method from a trigger, or you might hit a limit exception that is hard to debug.
4. The Order of Execution
You don’t need to memorize all 20 steps, but you should know the big ones. When you save a record, Salesforce runs system validation, “Before” triggers, custom validation rules, “After” triggers, and then Flows. Knowing that validation rules run after “Before” triggers is a common trick question in many Apex Trigger Interview Questions sets.
5. Trigger Design Best Practices
When I’m reviewing code for a project, I look for these three things immediately:
- One Trigger Per Object: Don’t create five different triggers on the Account object. It makes the order of execution impossible to predict.
- Logic-Less Triggers: Your trigger should just be a router. Move the actual “meat” of the code into a Handler class.
- Bulkification: No queries in loops. Ever.
If you want to see how these concepts fit into a broader interview, I’ve put together a list of scenario-based questions that go deeper into these patterns. It’s one thing to know the syntax, but another to know deciding when to use code over Flow in a real project.
Example: Preventing Deletion with Logic
Here is a classic scenario: “Prevent an Account from being deleted if it has related Contacts.” You’ll use addError() on Trigger.old to stop the transaction. Notice the use of an Aggregate query to stay bulkified.
trigger AccountDeleteGuard on Account (before delete) {
Set<Id> accIds = new Set<Id>();
for(Account acc : Trigger.old) accIds.add(acc.Id);
Map<Id, AggregateResult> results = new Map<Id, AggregateResult>([
SELECT AccountId Id, COUNT(Id) cnt FROM Contact
WHERE AccountId IN :accIds GROUP BY AccountId
]);
for(Account acc : Trigger.old){
if(results.containsKey(acc.Id)){
acc.addError('You cannot delete this account because it has active contacts.');
}
}
}Key Takeaways for Your Interview
- Before triggers are for field updates; After triggers are for related record logic.
- Always use a Map/Set pattern to keep your code bulkified.
- Use a static boolean flag in a helper class to prevent recursive loops.
- Keep your triggers “thin” by moving logic to handler classes.
- Mention
addError()as the way to block DML based on custom business logic.
At the end of the day, the person interviewing you wants to know if they can trust you with their code base. If you talk about bulkification, handler patterns, and governor limits, you are already ahead of 90% of the other candidates. Focus on the “why” behind the code, and you will do just fine.








2 Comments