---
schema_version: "1"
id: abc05e52c5aa6c23d5bb0498cb4ed6ff240b0230554b8a897d89c5baa78ceebb
title: Trigger and Bulk Request Best Practices
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/apex_triggers_bestpract.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_bestpract.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 243b717f6f6a8581d013ad33c0a4a4f88e2316122cb9b0f7c668158fde68d6bf
---
# Trigger and Bulk Request Best Practices

A common development pitfall is the assumption that trigger invocations never include more than one record. Apex triggers are optimized to operate in bulk, which, by definition, requires developers to write logic that supports bulk operations.

This is an example of a flawed programming pattern. It assumes that only one record is pulled in during a trigger invocation. While this might support most user interface events, it does not support bulk operations invoked through SOAP API or Visualforce.

trigger MileageTrigger on Mileage\_\_c (before insert, before update) {
   User c = \[SELECT Id FROM User WHERE Mileageid\_\_c = :Trigger.new\[0\].Id WITH USER\_MODE\];
}

This is another example of a flawed programming pattern. It assumes that fewer than 100 records are in scope during a trigger invocation. If more than 100 queries are issued, the trigger would exceed the SOQL query limit.

trigger MileageTrigger on Mileage\_\_c (before insert, before update) {
   for(Mileage\_\_c m : Trigger.new){ 
      User c = \[SELECT Id FROM user WHERE Mileageid\_\_c = :m.Id WITH USER\_MODE\];
   }
}

For more information on governor limits, see [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm "Because Apex runs in a multitenant environment, the Apex runtime engine strictly enforces limits so that runaway Apex code or processes don’t monopolize shared resources. If some Apex code exceeds a limit, the associated governor issues a runtime exception that can’t be handled.").

This example demonstrates the correct pattern to support the bulk nature of triggers while respecting the governor limits:

trigger MileageTrigger on Mileage\_\_c (before update) {
   Set<Id> ids = Trigger.newMap.keySet();
   List<User> c = \[SELECT Id FROM user WHERE mileageid\_\_c in :ids WITH USER\_MODE\];
}

This pattern respects the bulk nature of the trigger by passing the Trigger.new collection to a set, then using the set in a single SOQL query. This pattern captures all incoming records within the request while limiting the number of SOQL queries.

## Best Practices for Designing Bulk Programs

The following are the best practices for this design pattern:

- Minimize the number of data manipulation language (DML) operations by adding records to collections and performing DML operations against these collections.
- Minimize the number of SOQL statements by preprocessing records and generating sets, which can be placed in single SOQL statement used with the IN clause.

- [← Previous](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_exceptions.htm "Trigger Exceptions")

#### See Also

- [Developing Code in the Cloud](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_intro_apex_limitation.htm "The Apex programming language is saved and runs in the cloud—the multitenant platform. Apex is tailored for data access and data manipulation on the platform, and it enables you to add custom business logic to system events. While it provides many benefits for automating business processes on the platform, it is not a general purpose programming language.")