Apex Trigger Cheat Sheet — Master Triggers in Salesforce (2025)

A compact, interview-ready guide to Apex Triggers: syntax, context variables, best practices, handler patterns, and test examples to help Salesforce developers build scalable automation in 2025.

Introduction

Apex Triggers are essential for database-level automation in Salesforce. This guide covers trigger events, context variables, a real-world example (auto-create Task on Opportunity Closed Won), best practices for 2025, and a reusable handler pattern with test code.

What is an Apex Trigger?

An Apex Trigger runs automatically in response to DML events (insert, update, delete, undelete) on Salesforce objects. Triggers give developers fine-grained control over operations that can’t be achieved with clicks alone.

Trigger Events & When to Use Them

Triggers can execute before or after DML events. Common scenarios:

  • before insert/update: modify or validate record values before save
  • after insert/update: create or update related objects
  • after delete: cascade cleanup or auditing

Basic Trigger Syntax

trigger AccountTrigger on Account (before insert, after update) {
    if(Trigger.isBefore && Trigger.isInsert){
        // Logic before account insert
    }
    if(Trigger.isAfter && Trigger.isUpdate){
        // Logic after account update
    }
}

Trigger Context Variables

Context variables expose the records and execution state in a trigger:

  • Trigger.new — List of new records
  • Trigger.old — List of old records (for update/delete)
  • Trigger.newMap / Trigger.oldMap — Map<Id, sObject> for quick lookups
  • Trigger.isBefore / isAfter and Trigger.isInsert / isUpdate / isDelete
  • Trigger.size — Number of records in this context

Real-World Example: Auto Create Task on Opportunity Closed Won

trigger OpportunityTrigger on Opportunity (after update) {
    List taskList = new List();
    for(Opportunity opp : Trigger.new){
        if(opp.StageName == 'Closed Won' &&
           Trigger.oldMap.get(opp.Id).StageName != 'Closed Won'){
            taskList.add(new Task(
                Subject = 'Follow up with customer',
                WhatId = opp.Id,
                Status = 'Not Started',
                Priority = 'High'
            ));
        }
    }
    if(!taskList.isEmpty())
        insert taskList;
}

Apex Trigger Best Practices (2025 Edition)

Keep your org scalable and maintainable by following these guidelines:

  • One trigger per object — keep triggers thin and delegate logic to handler classes
  • Bulkify everything — assume multi-record contexts and avoid DML/SOQL inside loops
  • Use collections (List, Set, Map) for efficient data processing
  • Handle recursion with static variables or a framework to prevent re-entry loops
  • Rely on context variables to control execution flow
  • Write robust unit tests — aim for meaningful assertions and coverage
  • Use Async Apex (@future, Queueable, Batchable) for heavy post-DML processing

Trigger Framework Example (Handler Pattern)

Example trigger that delegates to a handler class:

trigger AccountTrigger on Account (before insert, after update) {
    AccountTriggerHandler handler = new AccountTriggerHandler();
    if(Trigger.isBefore && Trigger.isInsert)
        handler.beforeInsert(Trigger.new);
    if(Trigger.isAfter && Trigger.isUpdate)
        handler.afterUpdate(Trigger.new, Trigger.oldMap);
}

Handler Class

public class AccountTriggerHandler {
    public void beforeInsert(List accList){
        for(Account acc : accList){
            acc.Description = 'Created via Trigger';
        }
    }
    public void afterUpdate(List newList, Map oldMap){
        // Additional post-update logic here
    }
}

Test Class Example

@isTest
private class AccountTriggerTest {
    @isTest static void testBeforeInsert() {
        Account acc = new Account(Name='Test Account');
        insert acc;

        Account inserted = [SELECT Description FROM Account WHERE Id=:acc.Id];
        System.assertEquals('Created via Trigger', inserted.Description);
    }
}

Common Interview Scenarios

Typical problems asked in interviews that test trigger knowledge:

  • Prevent duplicate records (SOQL + validation logic)
  • Auto-create child records (after insert)
  • Prevent recursive updates (static variable patterns)
  • Update related records efficiently (after update + collections)
  • Async processing for heavy jobs (Queueable / Batch)

Key Takeaways

  • Use one trigger per object and move logic to handlers
  • Bulk-safe your code and avoid expensive operations in loops
  • Write unit tests with assertions to validate logic
  • Use asynchronous patterns for post-DML heavy work

Why this matters for Salesforce teams

Well-designed triggers keep Salesforce orgs performant, reduce deployment friction, and make maintenance predictable. For admins, understanding trigger behavior helps when debugging automation conflicts. For developers, mastering these patterns is crucial for delivering enterprise-grade solutions. For business users, it ensures automation behaves reliably as data volumes grow.