---
schema_version: "1"
id: 247eea591da19559e0a632cf075d384c70fb2cb6ff99117cb2b00b016fa52274
title: Trigger Context Variables
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/apex_triggers_context_variables.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 9fff62e80031e0c0246603bd06ebf5219488de61074b301e99b60e2b8b432e7a
description: All triggers define implicit variables that allow developers to access run-time context. These variables are contained in the System.Trigger class.
---
# Trigger Context Variables

All triggers define implicit variables that allow developers to access run-time context. These variables are contained in the System.Trigger class.

Here are the trigger context variables.

<table class="featureTable sort_table" summary="">


        <thead class="thead sorted" align="left">
          <tr>
            <th class="featureTableHeader vertical-align-top " id="d139793e49">Variable</th>

            <th class="featureTableHeader vertical-align-top " id="d139793e52">Usage</th>

          </tr>

        </thead>

        <tbody class="tbody">
          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isExecuting</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if the current
              context for the Apex code is a trigger, not a Visualforce page, a web
              service, or an <samp class="codeph nolang">executeanonymous()</samp>
              API call.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isInsert</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired due to an insert operation, from the Salesforce user
              interface, Apex, or the API.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isUpdate</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired due to an update operation, from the Salesforce user
              interface, Apex, or the API.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isDelete</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired due to a delete operation, from the Salesforce user interface,
              Apex, or the API.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isBefore</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired before any record was saved.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isAfter</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired after all records were saved.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">isUndelete</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns <samp class="codeph apex_code"><span class="keyword">true</span></samp> if this trigger
              was fired after a record is recovered from the Recycle Bin. This
              recovery can occur after an undelete operation from the Salesforce user
              interface, Apex, or the API.</td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code"><span class="keyword">new</span></samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns a list of the new versions of the sObject records.<p class="p">This
                sObject list is only available in <samp class="codeph nolang">insert</samp>, <samp class="codeph nolang">update</samp>,
                and <samp class="codeph nolang">undelete</samp> triggers, and the
                records can only be modified in <samp class="codeph nolang">before</samp> triggers.</p>
            </td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">newMap</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">A map of IDs to the new versions of the sObject records.<p class="p">This map
                is only available in <samp class="codeph nolang">before
                  update</samp>, <samp class="codeph nolang">after
                  insert</samp>, <samp class="codeph nolang">after
                  update</samp>, and <samp class="codeph nolang">after
                  undelete</samp> triggers. </p>
            </td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">old</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns a list of the old versions of the sObject records.<p class="p">This
                sObject list is only available in <samp class="codeph nolang">update</samp> and <samp class="codeph nolang">delete</samp>
                triggers.</p>
            </td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">oldMap</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">A map of IDs to the old versions of the sObject records.<p class="p">This map
                is only available in <samp class="codeph nolang">update</samp> and
                <samp class="codeph nolang">delete</samp> triggers.
              </p>
            </td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">operationType</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">Returns an enum of type <samp class="codeph nolang">System.TriggerOperation</samp> corresponding to the current
              operation.<p class="p">Possible values of the System.TriggerOperation enum
                are: <samp class="codeph nolang">BEFORE_INSERT</samp>, <samp class="codeph nolang">BEFORE_UPDATE</samp>, <samp class="codeph nolang">BEFORE_DELETE</samp>,<samp class="codeph nolang">AFTER_INSERT</samp>, <samp class="codeph nolang">AFTER_UPDATE</samp>, <samp class="codeph nolang">AFTER_DELETE</samp>, and <samp class="codeph nolang">AFTER_UNDELETE</samp>. If you vary your
                programming logic based on different trigger types, consider using
                the <samp class="codeph apex_code"><span class="statement">switch</span></samp> statement with
                different permutations of unique trigger execution enum
                states.</p>
            </td>

          </tr>

          <tr>
            <td class="entry" headers="d139793e49" data-title="Variable"><samp class="codeph apex_code">size</samp></td>

            <td class="entry" headers="d139793e52" data-title="Usage">The number of records processed in a trigger invocation. DML
              operations that include over 200 records are processed in batches, and
              the trigger is invoked for each batch. <samp class="codeph apex_code">Trigger.size</samp> includes only the number of records in the
              current batch, not the total number of records in the DML
              operation.</td>

          </tr>

        </tbody>

      </table>

![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)

#### Note

The record firing a trigger can include an invalid field value, such as a formula that divides by zero. In this case, the field value is set to null in these variables:

- new
- newMap
- old
- oldMap

For example, in this simple trigger, Trigger.new is a list of sObjects and can be iterated over in a for loop. It can also be used as a bind variable in the IN clause of a SOQL query.

trigger SimpleTrigger on Account(after insert) {
  for (Account a : Trigger.new) {
    // Iterate over each sObject
  }

  // This single query finds every contact that is associated with any of the
  // triggering accounts. Note that although Trigger.new is a collection of
  // records, when used as a bind variable in a SOQL query, Apex automatically
  // transforms the list of records into a list of corresponding Ids.
  Contact\[\] cons = \[
    SELECT LastName
    FROM Contact
    WHERE AccountId IN :Trigger.new
    WITH USER\_MODE
  \];
}

This trigger uses Boolean context variables such as Trigger.isBefore and Trigger.isDelete to define code that only executes for specific trigger conditions:

trigger MyAccountTrigger on Account(
  before delete,
  before insert,
  before update,
  after delete,
  after insert,
  after update
) {
  if (Trigger.isBefore) {
    if (Trigger.isDelete) {
      // In a before delete trigger, the trigger accesses the records that will be
      // deleted with the Trigger.old list.
      for (Account a : Trigger.old) {
        if (a.name != 'okToDelete') {
          a.addError('You can\\'t delete this record!');
        }
      }
    } else {
      // In before insert or before update triggers, the trigger accesses the new records
      // with the Trigger.new list.
      for (Account a : Trigger.new) {
        if (a.name == 'bad') {
          a.name.addError('Bad name');
        }
      }
      if (Trigger.isInsert) {
        for (Account a : Trigger.new) {
          Assert.areEqual('xxx', a.accountNumber);
          Assert.areEqual('industry', a.industry);
          Assert.areEqual(100, a.numberofemployees);
          Assert.areEqual(100.0, a.annualrevenue);
          a.accountNumber = 'yyy';
        }

        // If the trigger is not a before trigger, it must be an after trigger.
      } else {
        if (Trigger.isInsert) {
          List<Contact> contacts = new List<Contact>();
          for (Account a : Trigger.new) {
            if (a.Name == 'makeContact') {
              contacts.add(new Contact(LastName = a.Name, AccountId = a.Id));
            }
          }
          insert as user contacts;
        }
      }
    }
  }
}

- [← Previous](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_syntax.htm "Trigger Syntax")
- [Next →](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm "Context Variable Considerations")

#### See Also

- [_Apex Reference Guide_: TriggerOperation Enum](https://developer.salesforce.com/docs/atlas.en-us.264.0.apexref.meta/apexref/apex_enum_System_TriggerOperation.htm "Apex Reference Guide: TriggerOperation Enum - HTML (New Window)")
- [Switch Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_switch.htm "Apex provides a switch statement that tests whether an expression matches one of several values and branches accordingly.")