Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating the key differences between Salesforce Trigger.new and Trigger.newMap for Apex developers
Apex

Trigger.new vs Trigger.newMap — Key Differences in Salesforce Apex Triggers

The short answer

Trigger.new is a list of the incoming sObject records. Trigger.newMap is a map of record Ids to those same sObject instances. Picking the right context variable saves unnecessary loops, avoids CPU timeouts, and keeps the code safe across different trigger events.

Key takeaways Use Trigger.new for simple field checks and for before insert logic, where the records have no Ids yet. Use Trigger.newMap for O(1) lookups by Id instead of nesting loops to find a record. Pair Trigger.newMap with Trigger.oldMap in update triggers to compare old and new field values cleanly. Check the context variable before you use it, because Trigger.newMap is always null in before insert.

If you have spent any time writing Apex, you have wrestled with Trigger.new and Trigger.newMap. It looks simple until you are staring at a MapException or working out why your code crawls. Plenty of developers default to lists for everything because lists feel comfortable, and in a large org that habit eventually bites.

Choosing the wrong one leads to messy nested loops or logic that does not scale. Here is how each one behaves and when I reach for it.

Understanding Trigger.new vs Trigger.newMap in real scenarios

Trigger.new is a List<sObject>. It holds the new versions of whatever records just hit the trigger. For simple field validation, or a basic update where you do not need to look anything else up, that is all you need. I reach for it when the job is looping through everything and checking a value. Making sure a field is not empty before the record saves is a for-each loop on the list and nothing more.

Lists are good at order and bad at finding a specific record by its Id. Finding one Account in a list of 200 means walking the whole list, which wastes resources you did not need to spend.

A diagram comparing a linear search through an Apex list with a direct key lookup in an Apex map.

The list walks every element to find one record. The map goes straight to it.

Which one should you pick? Trigger.new vs Trigger.newMap

Trigger.newMap is a Map<Id, sObject>. Hand it an Id and the record comes back instantly, no looping required. Juniors who are trying to get their code past a unit test overlook this more than anything else.

In my experience this is where the performance actually comes from. Comparing new values against old values, or cross-referencing records from a different collection, wants a map. Most teams get this wrong on their first complex trigger and end up with code that hits CPU limits during bulk uploads.

Pro tip: check your context variable for null before you start calling methods on it. It sounds obvious, and it is still a common cause of trigger failures when someone uses Trigger.newMap in a before insert context.

Availability and context gotchas

These are not always available. In a before insert trigger the records have no Ids yet, because nothing has been saved to the database, so Trigger.newMap is null. I have watched senior devs forget that and break a deployment. It happens to the best of us.

  • Trigger.new is available in almost every context except delete.
  • Trigger.newMap is available in after insert, and all update and undelete events.

Still getting comfortable with how these fire? Start with this guide on what a Salesforce Apex Trigger is. The post on Apex trigger interview questions shows how these concepts get tested in the real world.

Practical example: comparing changes

Checking whether a field changed during an update is the classic case, and this is where the distinction really matters. Use Trigger.newMap alongside Trigger.oldMap for the side-by-side comparison. It is much cleaner than juggling two separate lists.

// Fast way to check for changes
for (Id accId : Trigger.newMap.keySet()) {
    Account newRecord = Trigger.newMap.get(accId);
    Account oldRecord = Trigger.oldMap.get(accId);

    if (newRecord.AnnualRevenue != oldRecord.AnnualRevenue) {
        // The revenue changed, so take action here
    }
}

That is an "O(1)" lookup instead of an "O(n)" loop. When you are dealing with large data volumes, the difference decides whether your code runs in 100ms or 5 seconds.

Key takeaways

When you are deciding between the two, keep these points in mind.

  • Use Trigger.new for simple iteration and before insert logic where Ids do not exist yet.
  • Use Trigger.newMap for fast lookups and for comparing old and new values.
  • Avoid nested loops by using the map to find related records by Id.
  • Remember that Trigger.newMap is null in before insert.

If you only need to check a value on the record itself, the list is fine. Anything involving Ids or comparisons wants the map. Make that your default for lookups and the code stays fast when the bulk loads arrive.

Frequently asked questions

What is the difference between Trigger.new and Trigger.newMap?

Trigger.new is a List<sObject> holding the new versions of the records that fired the trigger. Trigger.newMap is a Map<Id, sObject> that maps record Ids to those same instances. Trigger.new suits sequential iteration, while Trigger.newMap gives you instant retrieval by key.

Why is Trigger.newMap null in before insert?

In a before insert trigger the records have not been saved to the database yet, so they have no Salesforce Ids and Trigger.newMap is null. Iterate over Trigger.new in that context instead.

When should you use Trigger.newMap over Trigger.new?

Use Trigger.newMap when you need to look up records by Id, cross-reference collections, or compare field changes against Trigger.oldMap. The O(1) lookup cuts CPU time and removes nested loops during bulk processing.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment