Skip to main content

SF-0323 · Concept · Easy

What is a trigger?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

An Apex trigger is a special kind of Apex code that runs automatically whenever records of a specific object are created, changed, deleted, or restored. Think of it as a database hook: you point it at an object — say Account or Case — and Salesforce calls your code at the moments you specify in the trigger declaration.

Trigger anatomy

trigger AccountTrigger on Account (
    before insert, before update, before delete,
    after insert, after update, after delete, after undelete
) {
    if (Trigger.isBefore && Trigger.isInsert) {
        AccountHandler.setDefaultRating(Trigger.new);
    }
    if (Trigger.isAfter && Trigger.isUpdate) {
        AccountHandler.recalcOpportunityTotals(Trigger.new, Trigger.oldMap);
    }
}

Three things to notice:

  1. The events list declares when the trigger runs. You can register for any combination of seven events (before/after × insert/update/delete + after undelete).
  2. Context variablesTrigger.new, Trigger.old, Trigger.newMap, Trigger.oldMap, Trigger.isBefore, Trigger.isAfter, and so on — tell you what just happened and give you access to the records.
  3. The trigger body should be thin. Salesforce’s recommended pattern is one trigger per object, and that trigger delegates to a handler class. You almost never want business logic inline in the trigger file.

Before vs after — when to use which

Use a before trigger when you want to…Use an after trigger when you want to…
Modify field values on the records being saved (no DML needed — just assign in place)Create or update related records (e.g. child records that reference the just-inserted parent’s Id)
Validate input and call record.addError('msg') to block the saveSend platform events or fire callouts (via @future or queueable)
Pre-compute derived fields that depend only on the record’s own valuesRoll up counts onto parent records

The big trap: Trigger.new is read-only in after context. If you try to assign to it after an insert/update has already happened, the runtime will throw.

Bulkification — the non-negotiable rule

Apex triggers always receive a collection of records, even if a single record was edited in the UI. Why? Because the same trigger fires for data loader imports, API calls, and async jobs, each of which can deliver up to 200 records per trigger invocation. Code that loops one record at a time and does a SOQL query inside that loop will blow governor limits the first time a real workload hits production.

A bulk-safe pattern:

trigger CaseTrigger on Case (after update) {
    // Gather the parent IDs we care about
    Set<Id> accountIds = new Set<Id>();
    for (Case c : Trigger.new) {
        if (c.AccountId != null) accountIds.add(c.AccountId);
    }
    // One query, regardless of how many cases changed
    Map<Id, Account> accountsById = new Map<Id, Account>([
        SELECT Id, Open_Cases__c FROM Account WHERE Id IN :accountIds
    ]);
    // ... mutate and update in bulk
}

Common interview follow-ups

  • “Walk me through the order of execution when a record is saved.” — Flag this as worth memorising: validation rules, before triggers, system validation, after triggers, assignment rules, auto-response rules, workflow field updates, post-commit logic. Many interviewers ask this verbatim.
  • “What’s the difference between Trigger.new and Trigger.newMap?” — new is List<SObject>, newMap is Map<Id, SObject>. newMap is null in before insert because records don’t have IDs yet.
  • “Why use a trigger framework?” — to handle recursion guards, ordering, skip flags, and per-context disabling cleanly. Most production orgs use a framework like fflib or a custom one rather than raw triggers.

When NOT to use a trigger

If Flow, validation rules, or formula fields can solve it, prefer those. Triggers are the most powerful tool — and the most likely to introduce regressions, governor-limit issues, and test-coverage debt. The unofficial Salesforce rule: Apex only when configuration can’t.

Verified against: Apex Developer Guide — Triggers, Trailhead module Apex Triggers. Last reviewed 2026-05-17 for Spring ‘26 release.