Welcome to Triggerhours!

If you are looking to sharpen your Salesforce development skills with real-world examples and practical tutorials, you are in the right place. To help you prepare for your next big role, we have compiled the ultimate list of the top 50 Salesforce Apex Trigger interview questions.

This guide progresses from fundamental concepts to complex, enterprise-level architectural scenarios. Whether you are aiming for a junior developer position or a senior architect role, you will find clean, scalable Apex answers that solve tough problems and strictly follow Salesforce best practices.

Let’s dive into the questions.

1. What is an Apex Trigger in Salesforce?

An Apex Trigger is a block of code that executes before or after specific data manipulation language (DML) operations such as insert, update, delete, or undelete on Salesforce records. Triggers allow developers to perform custom actions like complex validation, record updates, or external integrations automatically.

2. What are the two types of triggers in Salesforce?

Salesforce supports two primary types of triggers:

  • Before Triggers: Execute before the data is saved to the database. They are primarily used to validate or modify record values before they are committed.
  • After Triggers: Execute after the data has been saved to the database. They are ideal for operations that require the system-generated record ID (like creating related child records).

3. What are the different events available in triggers?

Triggers can run during seven distinct events in a record’s lifecycle:

1. before insert
2. before update
3. before delete
4. after insert
5. after update
6. after delete
7. after undelete

4. When should you use an Apex Trigger versus a Flow?

Use declarative automation tools like Salesforce Flow for straightforward tasks such as simple field updates, email alerts, or basic cross-object updates. Opt for Apex Triggers when dealing with massive bulk data operations, highly complex business logic, complex integrations, or when order of execution performance is critical.

5. What are the core best practices for writing Apex triggers?

Top best practices include:

  • Bulkification: Ensure your code handles multiple records efficiently without hitting limits.
  • One Trigger per Object: Prevent execution order conflicts by keeping only one trigger per sObject.
  • Logicless Triggers: Use the Trigger Handler pattern to move business logic out of the trigger file and into a dedicated Apex class.
  • No Hardcoding: Use Custom Metadata Types or Custom Labels instead of hardcoding IDs.

6. How many times does a trigger execute on an Upsert event?

An Upsert operation can cause a trigger to fire multiple times depending on the data.
For new records, it fires before insert and after insert.
For existing records, it fires before update and after update.

7. How many times does a trigger execute on a Merge event?

During a merge operation, the losing record fires before delete and after delete. The winning record then fires before update and after update.

8. What is the Salesforce Order of Execution?

Understanding the order of execution is critical for data integrity. The simplified sequence is:

  1. System Validation Rules
  2. Before Triggers
  3. Custom Validation Rules
  4. Duplicate Rules
  5. After Triggers
  6. Assignment & Auto-Response Rules
  7. Workflow Rules & Processes/Flows
  8. Escalation Rules
  9. Roll-up Summary Fields
  10. Commit to Database

9. When would you choose a before event versus an after event?

Choose a before event to validate data or update fields on the exact records that fired the trigger (no DML required). Choose an after event if you need to query related records, update a different object, or if you need the newly generated Record ID of the inserted record.

10. What is the difference between Trigger.new and Trigger.newMap?

Trigger.new is a List containing the new versions of the sObject records being processed. Trigger.newMap is a Map where the key is the record ID and the value is the new version of the record. Trigger.newMap is highly useful for comparing old and new values, but it is only available in before update, after insert, after update, and after undelete contexts.

11. When should you use Trigger.old and Trigger.oldMap?

These context variables are used to access the previous versions of records before the DML operation occurred. They are essential in update triggers to check if a specific field’s value has actually changed before executing heavy logic.

12. What is the Trigger Handler Pattern and why is it important?

The Trigger Handler pattern is an architectural design that separates the trigger’s routing logic from the actual business logic. It promotes cleaner code, enhances reusability, makes unit testing significantly easier, and allows developers to control the exact execution flow of the transaction.

13. How do you handle bulk operations in triggers?

To handle bulk operations, you must never write SOQL queries or DML statements inside a for loop. Instead, use loops to gather data (like parent IDs) into collections (Lists, Sets, Maps), run a single query using those collections, and then perform a single DML operation on a compiled list of records.

14. Can a batch job be called from a trigger context?

Yes, you can invoke a Batch job from a trigger. However, it is essential to ensure that the batch is called responsibly, as Salesforce limits the number of concurrent batch jobs. It is often used when a trigger needs to process a massive volume of related records asynchronously.

15. What is the difference between trigger context variables and static variables?

Context variables (like Trigger.isInsert) provide information about the current state of the database transaction. Static variables are stored in Apex classes and maintain their state across the entire execution transaction, making them perfect for preventing recursive trigger loops.

16. What are the most common governor limits to watch out for in triggers?

The most critical limits in synchronous transactions include:

  • 100 SOQL queries
  • 150 DML statements
  • 50,000 total records retrieved by SOQL
  • 10,000 total records processed by DML
  • 10 seconds of CPU time

17. How do you ensure triggers respect user access permissions?

By default, triggers run in System Mode, ignoring user permissions. To enforce security, delegate the trigger logic to a handler class defined with the with sharing keyword. This ensures the logic respects the record-level sharing rules of the user triggering the action.

18. How do you effectively test triggers in Salesforce?

Effective trigger testing involves writing Apex test classes that simulate single-record and bulk-record scenarios (e.g., passing 200 records at once). Use Test.startTest() and Test.stopTest() to reset governor limits, and use System.runAs() to test the code under different user profiles to catch permission errors.

19. What is the purpose of using Custom Metadata Types in trigger development?

Custom Metadata Types act as configuration data for your code. By using them, you can create a “bypass” toggle to turn specific triggers on or off directly from the UI without deploying new code, which is invaluable during large data migrations.

20. Can we perform DML operations in a before trigger?

While technically possible on other objects, you should never perform DML on the records currently in the Trigger.new context of a before trigger. Doing so is unnecessary and can cause recursion. Simply update the field values directly in memory, and Salesforce will save them automatically.

21. What is Trigger.size() used for?

Trigger.size() returns the total number of records that invoked the trigger. It is useful for implementing conditional logic—for example, routing logic differently or logging a warning if the trigger is processing a massive bulk API job versus a single UI update.

22. Can a trigger directly invoke another trigger?

Triggers do not directly call other triggers. However, if Object A’s trigger performs a DML operation on Object B, and Object B has its own trigger, Object B’s trigger will automatically fire. Developers must manage this carefully to avoid chained limit exceptions.

23. What are some common real-world use cases for triggers?

Common scenarios include automatically creating standard child records when a parent is created, preventing duplicate record creation based on complex logic, rolling up values across lookup relationships, and syncing data with external ERP systems.

24. How do you use the addError() method effectively?

The addError() method prevents a DML operation from completing and attaches a user-friendly error message to the UI. It should generally be used in Before Triggers to block invalid data from saving.

for(Account acc : Trigger.new){
    if(acc.AnnualRevenue < 1000){
        acc.addError('Annual Revenue must be greater than 1,000.'); 
    }
}


25. What happens if a trigger fails in a Bulk DML Operation?

If one record in a standard bulk operation fails due to an unhandled trigger exception, the entire chunk rolls back, and none of the records are committed. To prevent this, handle exceptions using try-catch blocks and use Database.insert(records, false) to allow partial success.

26. How do you prevent recursion when Flow and Apex both update the same record?

When a record is updated via Apex, it triggers a Flow, which might update the record again, causing the Apex trigger to fire a second time. Do not use a simple static Boolean (e.g., isFirstRun = false). In bulk operations exceeding 200 records, Salesforce chunks the execution, and a simple boolean will block the second chunk from processing! Instead, use a static Set<Id> to store the IDs of records that have already been processed.

public class AccountTriggerHandler {
    public static Set<Id> processedRecordIds = new Set<Id>();
    
    public static void handleAfterUpdate(List<Account> newList) {
        List<Account> accountsToProcess = new List<Account>();
        for(Account acc : newList) {
            if(!processedRecordIds.contains(acc.Id)) {
                accountsToProcess.add(acc);
                processedRecordIds.add(acc.Id); // Mark as processed
            }
        }
        // Process accountsToProcess
    }
}


27. How do you handle 10k+ record bulk updates without hitting limits?

Triggers must be lightweight. If a bulk API job pushes 10,000 records, synchronous trigger logic will likely hit CPU time or SOQL limits. Ensure absolute bulkification (no queries or DML in loops). Then, defer heavy processing. Instead of running complex logic synchronously, have the trigger enqueue a Queueable job or publish a Platform Event. This moves the heavy lifting to an asynchronous thread with its own limits.

28. How do you redesign a trigger failing due to Mixed DML in production?

A “Mixed DML” exception occurs when you try to insert/update a Setup object (like User or Profile) and a non-Setup object (like Account) in the same synchronous transaction. Isolate the DML operations. Move the DML for the Setup object (or the non-Setup object) into an asynchronous context using an @future method or a Queueable Apex class.

29. How do you avoid record locking when updating parent-child records?

When multiple child records linked to the same parent are updated simultaneously in different threads (e.g., via an integration), the parent record gets locked, throwing an UNABLE_TO_LOCK_ROW error. Sort the parent IDs in Apex before performing the DML. Salesforce processes updates sequentially based on the list order. Sorting the list forces Salesforce to lock and release the parent records in a predictable, organized sequence, drastically reducing lock contention.

30. How do you design a scalable trigger framework?

A scalable enterprise framework (like Kevin O’Hara’s or fflib) should include:

  • One Trigger per Object: A single trigger that delegates logic to a handler.
  • Handler Interface: Methods strictly separated by context (beforeInsert, afterUpdate).
  • Service Layer: Moving business logic out of the handler and into a reusable Service class.
  • Bypass Mechanism: Custom Metadata Types to turn triggers on/off safely.

31. How do you safely perform callouts from trigger context?

Triggers run synchronously and cannot wait for an external server to respond. Use asynchronous Apex. Call an @future(callout=true) method or enqueue a Queueable class that implements Database.AllowsCallouts. Pro-Tip: Do not pass the Trigger.new list of sObjects to the async method. Pass a Set<Id> instead, and requery the records to ensure you have the latest data.

32. How do you ensure idempotency when integrations retry?

If an external integration fails to receive a success response, it might retry the payload, causing duplicate records in your trigger. Create an External_Transaction_ID__c field (marked as Unique/External ID). Use Database.upsert with this External ID so retries simply update the existing record instead of creating duplicates.

33. How do you debug a trigger that fails only for an integration user?

Integration users often have restricted permissions. First, check the Integration Profile/Permission Sets for missing Object or Field-Level Security (FLS). Second, set up a Trace Flag specifically targeting the Integration User. Finally, check if the trigger handler uses with sharing restricting visibility to related records.

34. How do you detect dynamic field changes without hardcoding?

Sometimes you need to know if any field in a Field Set changed without writing 50 if statements. Use the SObject get() method combined with dynamic Schema methods:

Schema.FieldSet fieldSet = SObjectType.Account.FieldSets.MyFieldSet;
for(Account newAcc : Trigger.new) {
    Account oldAcc = Trigger.oldMap.get(newAcc.Id);
    for(Schema.FieldSetMember fsm : fieldSet.getFields()) {
        String fieldName = fsm.getFieldPath();
        if(newAcc.get(fieldName) != oldAcc.get(fieldName)) {
            // Dynamic field change detected!
        }
    }
}


35. How do you prevent governor limit failures in chained updates?

Chained updates happen when Object A updates Object B, which triggers and updates Object C. This shares the same synchronous transaction limits. Decouple the transactions using Platform Events. When Object A finishes its logic, publish a Platform Event. The trigger on the Platform Event handles Object B in a completely separate transaction with a fresh set of governor limits.

36. How do you handle partial failures in bulk processing?

If one record in a batch fails validation, the default behavior is a total rollback. Instead of standard DML (update accList;), use the Database class methods with allOrNone set to false: Database.update(accList, false);. Iterate through the Database.SaveResult array to log failed records and allow successful ones to commit.

37. How do you move heavy logic outside trigger context safely?

If the logic takes a long time (e.g., complex calculations across thousands of child records), offload it to a Queueable class. Queueable is preferred over @future because you can pass complex objects (like Lists of sObjects), chain jobs together, and monitor them natively in the Apex Jobs UI.

38. How do you manage order of execution conflicts?

If a Flow updates a field, the Before and After triggers fire again. Consolidate your automation. Move complex record-triggered flows into the Apex Trigger, or vice versa. If they must coexist, rely on strict static Set<Id> recursion guards in your Apex to ensure it ignores the second pass.

39. How do you design triggers for multi-object transactions?

When an Opportunity is Won, you might need to create an Order, Order Products, update the Account, and create a Contract. Managing DML order here is tough. Implement the Unit of Work pattern. This registers records to be inserted/updated in memory, manages relationships automatically, and executes all DML statements at the very end of the transaction in an optimized sequence.

40. How do you avoid SOQL 101 errors in real-world cases?

Beyond the basic “don’t query in a loop”, real-world SOQL 101 errors often come from hidden operations. Check for Flow loops that are triggering your Apex repeatedly. Consolidate queries by using Parent-Child subqueries (SELECT Id, (SELECT Id FROM Contacts) FROM Account) to get related data in a single statement. Cache repetitive configuration queries using Custom Metadata Types.

41. How do you handle concurrent updates from integrations?

If an external system sends three rapid-fire updates for the same Case within milliseconds, Salesforce might process them concurrently, causing locking. Use the FOR UPDATE keyword in your SOQL queries. This creates a pessimistic lock, forcing the second transaction to wait up to 10 seconds for the first one to finish before proceeding.

42. How do you enforce business logic across multiple entry points?

Logic hidden inside a Trigger Handler cannot be easily called by an LWC controller or a REST API. Implement a Service Layer. Your Trigger Handler should be “logicless” and simply pass Trigger.new to a dedicated Service Class (e.g., AccountService.calculateDiscount()). Your LWC can call that exact same service method, ensuring DRY (Don’t Repeat Yourself) code.

43. How do you write test classes for complex trigger frameworks?

Testing complex triggers often hits governor limits because the test setup creates massive data chains. Use a TriggerBypass utility to turn off triggers while inserting test setup data. Strictly use Test.startTest() and Test.stopTest() to reset limits right before the actual logic is tested.

44. How do you ensure triggers remain maintainable at scale?

Never write logic directly inside the .trigger file. Enforce strict naming conventions across your team (e.g., AccountTriggerHandler, AccountService). Consistently use Custom Metadata Types as “Kill Switches” to enable/disable specific methods easily.

45. How do you architect triggers for enterprise orgs?

Enterprise architecture requires a strict separation of concerns:

  • Domain Layer: Encapsulates object-specific behavior and validation.
  • Service Layer: Coordinates complex business logic spanning multiple objects.
  • Selector Layer: Centralizes all SOQL queries so they aren’t scattered across multiple handlers.
  • Unit of Work: Consolidates and optimizes DML statements.

46. What is the “with sharing” keyword and how does it affect triggers?

Triggers inherently run in System Mode. If you want your trigger handler logic to respect the record-level visibility of the specific user who initiated the action, you must declare the class using the with sharing keyword.

47. How do you manually calculate Roll-Up Summaries via Apex?

When relationships are Lookups (not Master-Detail), standard Roll-up Summaries are unavailable. Use after insert, after update, after delete, and after undelete. Collect the Parent IDs in a Set<Id>. Query the Parent object with an aggregate query [SELECT ParentId, COUNT(Id) FROM ChildObj WHERE ParentId IN :parentIds GROUP BY ParentId], map the results, and update the parents accordingly.

48. Can Triggers be used with Platform Events?

Yes. Triggers can be written on Platform Events (e.g., after insert). Platform Event triggers are highly powerful because they run under the Automated Process user in an asynchronous, decoupled transaction, making them the gold standard for event-driven architecture.

49. How do you handle triggers on objects with large data volumes (LDV)?

When working with LDV, queries can time out. Ensure you are indexing the fields used in your SOQL WHERE clauses. If updating millions of records, completely bypass standard triggers and process updates using Bulk API v2 with hard-delete enabled.

50. What is a “Race Condition” in triggers and how do you prevent it?

A race condition occurs when two processes attempt to update the exact same record simultaneously, and the outcome depends on which finishes first. Prevent this by using pessimistic locking (FOR UPDATE in SOQL) or by designing asynchronous queueable jobs that serialize the processing of specific record IDs.

Author

  • Trigger Hours

    TriggerHours is a platform built on a simple idea: "The best way to grow is to learn together". We request seasoned professionals from across the globe to share their hard-won expertise, giving you the in-depth tutorials and practical insights needed to accelerate your journey. Our mission is to empower you to solve complex challenges and become an invaluable member of the Ohana.


Discover more from Trigger Hours

Subscribe to get the latest posts sent to your email.

1 thought on “Top 50 Salesforce Apex Trigger Interview Questions & Answers”

Leave a Reply

Discover more from Trigger Hours

Subscribe now to keep reading and get access to the full archive.

Continue reading