Skip to main content

SF-0327 · Concept · Medium

What are Trigger context variables?

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

Trigger context variables are implicit variables Salesforce makes available inside every trigger. They tell you which event fired, which records are involved, and whether you’re running before or after the database commits — the information your handler needs to do the right thing.

The full list

VariableTypeWhat it gives you
Trigger.newList<SObject>The new versions of the records (post-change). Writable in before, read-only in after.
Trigger.oldList<SObject>The pre-change versions. Available in update/delete/undelete only. Always read-only.
Trigger.newMapMap<Id, SObject>Trigger.new indexed by Id. Null in before insert.
Trigger.oldMapMap<Id, SObject>Trigger.old indexed by Id. Available in update/delete/undelete.
Trigger.isInsertBooleanTrue if the event is an insert.
Trigger.isUpdateBooleanTrue if the event is an update.
Trigger.isDeleteBooleanTrue if the event is a delete.
Trigger.isUndeleteBooleanTrue if the event is an undelete.
Trigger.isBeforeBooleanTrue in a before context.
Trigger.isAfterBooleanTrue in an after context.
Trigger.isExecutingBooleanTrue if the current Apex run is inside a trigger.
Trigger.sizeIntegerNumber of records in the current invocation.
Trigger.operationTypeSystem.TriggerOperation enumSingle value capturing both timing and event (e.g. BEFORE_UPDATE, AFTER_INSERT).

Routing with operationType

The modern way to dispatch context-specific logic is the operationType enum, introduced in Winter ‘17:

trigger AccountTrigger on Account (
    before insert, before update,
    after insert, after update, after delete, after undelete
) {
    switch on Trigger.operationType {
        when BEFORE_INSERT { AccountHandler.beforeInsert(Trigger.new); }
        when BEFORE_UPDATE { AccountHandler.beforeUpdate(Trigger.new, Trigger.oldMap); }
        when AFTER_INSERT  { AccountHandler.afterInsert(Trigger.newMap); }
        when AFTER_UPDATE  { AccountHandler.afterUpdate(Trigger.newMap, Trigger.oldMap); }
        when AFTER_DELETE  { AccountHandler.afterDelete(Trigger.oldMap); }
        when AFTER_UNDELETE { AccountHandler.afterUndelete(Trigger.newMap); }
    }
}

A switch on operationType reads cleaner than nested isBefore && isInsert checks and exhausts all the cases for the compiler.

The traps

  • Trigger.new is read-only in after — assigning to a field on a record in Trigger.new after the save will throw at runtime.
  • Trigger.oldMap is null in before insert and after insert — there are no old records to compare against.
  • Trigger.new is null in delete contexts — you only have Trigger.old and Trigger.oldMap.
  • Context variables outside a trigger? Not allowed. Trigger.isExecuting lets you check before reading them in a shared utility class.

Common interview follow-ups

  • Is Trigger.newMap available in before insert? — No. Records don’t have Ids yet, so there’s nothing to map.
  • Can I modify Trigger.old? — No. It’s always read-only.
  • What’s the difference between Trigger.operationType and Trigger.isInsert/isBefore?operationType is a single enum capturing both dimensions and is the recommended modern style.

Verified against: Apex Developer Guide — Trigger Context Variables. Last reviewed 2026-05-17.