Apex Trigger Cheat Sheet – Master Salesforce Triggers

I’ve spent a lot of time fixing messy Salesforce orgs, and usually, the culprit is a trigger that someone wrote in a hurry without a plan. If you’re looking for a reliable Apex Trigger Cheat Sheet to keep your code clean and your deployments from failing, you’re in the right place. We’ve all been there-staring at a “Too many SOQL queries: 101” error because a loop wasn’t bulkified properly.

Why You Need a Solid Apex Trigger Cheat Sheet

Triggers are the backbone of serious automation in Salesforce. While Flow has gotten much better lately, there are still plenty of times when you need the speed and control of code. But here’s the thing: triggers are dangerous if you don’t follow the rules. If you’re deciding between tools, it’s worth checking out this guide on Apex vs Flow to see when code is actually necessary.

A trigger runs in response to DML events like insert, update, delete, or undelete. You have two main windows of opportunity: “before” and “after”. Use “before” triggers when you want to update fields on the same record or block a save with an error. Use “after” triggers when you need to create related records or access the ID of the record you just saved.

The Apex Trigger Cheat Sheet: Context Variables and Events

Look, nobody memorizes every single context variable, but you need to know the heavy hitters. These variables tell your code exactly what’s happening right now. Are we in an update? Is this the “before” or “after” phase? Here’s the breakdown of what you’ll actually use on a daily basis.

  • Trigger.new: A list of the new versions of the records. Available in insert, update, and undelete.
  • Trigger.old: A list of the old versions of the records. Available in update and delete.
  • Trigger.newMap: A map of IDs to the new records. Super useful for looking up related data.
  • Trigger.oldMap: A map of IDs to the old records. Essential for checking if a field value actually changed.
  • Trigger.isBefore / Trigger.isAfter: Boolean values to tell you which phase you’re in.

Basic Trigger Syntax

Keep your trigger file as simple as possible. You don’t want a thousand lines of logic sitting directly in the trigger. Instead, use a structure like this to route your logic to the right place.

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

One thing that trips people up is forgetting that Trigger.new is a list. Even if you’re only saving one record through the UI, Salesforce treats everything as a batch. Always, always write your code to handle a list of records.

Real-World Example: Auto-Create a Task

Let’s look at a common request: creating a follow-up task when an Opportunity is marked “Closed Won”. This is a classic “after update” scenario because we want to make sure the Opportunity save was successful before we start adding tasks. This Apex Trigger Cheat Sheet wouldn’t be complete without a practical code snippet.

trigger OpportunityTrigger on Opportunity (after update) {
    List<Task> tasksToCreate = new List<Task>();
    
    for (Opportunity opp : Trigger.new) {
        // Check if the stage changed to Closed Won
        Opportunity oldOpp = Trigger.oldMap.get(opp.Id);
        
        if (opp.StageName == 'Closed Won' && oldOpp.StageName != 'Closed Won') {
            tasksToCreate.add(new Task(
                Subject = 'Onboarding Call',
                WhatId = opp.Id,
                Status = 'Not Started'
            ));
        }
    }
    
    if (!tasksToCreate.isEmpty()) {
        insert tasksToCreate;
    }
}

Best Practices for 2025

Honestly, most teams get this wrong because they ignore the basics. If you want your org to scale, you have to be disciplined. Here’s my personal checklist for every project I work on.

  1. One Trigger Per Object: If you have multiple triggers on the same object, you can’t control the order they run in. That’s a recipe for bugs.
  2. Bulkify Everything: Never put a SOQL query or a DML statement inside a loop. Use Collections (Sets, Lists, Maps) to gather your data and process it all at once.
  3. Use a Handler Pattern: Move your logic into a separate class. It makes your code easier to test and much cleaner to read.
  4. Watch Out for Recursion: If your trigger updates the same record that fired it, you can end up in an infinite loop. Use a static variable or a framework to prevent this.
  5. Write Meaningful Tests: Coverage is just a number. Write tests that actually prove your logic works under different scenarios.

The Handler Pattern Example

So how does a handler actually look? It’s just a regular Apex class. Your trigger calls the class, and the class does the work. This keeps your trigger file thin and manageable.

public class AccountHandler {
    public void handleBeforeInsert(List<Account> newAccounts) {
        for (Account acc : newAccounts) {
            if (acc.Industry == null) {
                acc.Description = 'Please set an industry.';
            }
        }
    }
}

Preparing for Interviews

If you’re studying this Apex Trigger Cheat Sheet for an upcoming job hunt, you’ll likely face scenario-based questions. They’ll ask things like, “How do you prevent a record from being deleted?” or “How do you handle a trigger that needs to call an external API?” For more practice, I’d suggest looking at these Apex Trigger Interview Questions.

And remember, if you need to do heavy processing that doesn’t need to happen instantly, look into asynchronous options. Processing 10,000 records? Don’t do that in a synchronous trigger. Use a Queueable or Batch job instead.

Key Takeaways

  • Stick to one trigger per object to maintain control over execution order.
  • Use “before” triggers for same-record updates and “after” triggers for related record changes.
  • Never put SOQL or DML inside loops-always use collections.
  • Delegate your logic to a handler class to keep the trigger file clean.
  • Always check if field values actually changed using Trigger.oldMap before running logic.

Triggers don’t have to be a headache. If you follow these patterns and keep this Apex Trigger Cheat Sheet handy, you’ll write code that’s easy to maintain and won’t crash when your data volume grows. Now, go check your current triggers-are any of them running SOQL in a loop? It’s time to fix them.