Understanding Governor Limits in Salesforce Apex

Last updated on Nov 24 2021
Abha Kulkarni

Table of Contents

Understanding Governor Limits in Salesforce Apex

Governor execution limits ensure the efficient use of resources on the Force.com multitenant platform. It is the limit specified by the Salesforce.com on code execution for efficient processing.

What are Governor Limits?

As we know, Apex runs in multi-tenant environment, i.e., a single resource is shared by all the customers and organizations. So, it is necessary to make sure that no one monopolizes the resources and hence Salesforce.com has created the set of limits which governs and limits the code execution. Whenever any of the governor limits are crossed, it will throw error and will halt the execution of program.
From a Developer’s perspective, it is important to ensure that our code should be scalable and should not hit the limits.
All these limits are applied on per transaction basis. A single trigger execution is one transaction.
As we have seen, the trigger design pattern helps avoid the limit error. We will now see other important limits.

Avoiding SOQL Query Limit

You can issue only 100 queries per transaction, that is, when your code will issue more than 100 SOQL queries then it will throw error.
Example
This example shows how SOQL query limit can be reached −
The following trigger iterates over a list of customers and updates the child record’s (Invoice) description with string ‘Ok to Pay’.

// Helper class:Below code needs o be checked.
public class CustomerTriggerHelper {

public static void isAfterUpdateCall(Trigger.new) {
createInvoiceRecords(trigger.new);//Method call
updateCustomerDescription(trigger.new);
}

// Method To Create Invoice Records
public static void createInvoiceRecords (List<apex_customer__c> customerList) {
for (APEX_Customer__c objCustomer: customerList) {

if (objCustomer.APEX_Customer_Status__c == 'Active' &&
trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {

// condition to check the old value and new value
APEX_Invoice__c objInvoice = new APEX_Invoice__c();
objInvoice.APEX_Status__c = 'Pending';
InvoiceList.add(objInvoice);
}
}
insert InvoiceList; // DML to insert the Invoice List in SFDC
}

// Method to update the invoice records
public static updateCustomerDescription (List<apex_customer__c> customerList) {
for (APEX_Customer__c objCust: customerList) {
List<apex_customer__c> invList = [SELECT Id, Name,
APEX_Description__c FROM APEX_Invoice__c WHERE APEX_Customer__c = :objCust.id];

// This query will fire for the number of records customer list has and will
// hit the governor limit when records are more than 100
for (APEX_Invoice__c objInv: invList) {
objInv.APEX_Description__c = 'OK To Pay';
update objInv;
// Update invoice, this will also hit the governor limit for DML if large
// number(150) of records are there
}
}
}
}

When the ‘updateCustomerDescription’ method is called and the number of customer records are more than 100, then it will hit the SOQL limit. To avoid this, never write the SOQL query in the For Loop. In this case, the SOQL query has been written in the For loop.
Following is an example which will show how to avoid the DML as well as the SOQL limit. We have used the nested relationship query to fetch the invoice records and used the context variable trigger.newMap to get the map of id and Customer records.

// SOQL-Good Way to Write Query and avoid limit exception
// Helper Class
public class CustomerTriggerHelper {
public static void isAfterUpdateCall(Trigger.new) {
createInvoiceRecords(trigger.new); //Method call
updateCustomerDescription(trigger.new, trigger.newMap);
}

// Method To Create Invoice Records
public static void createInvoiceRecords (List<apex_customer__c> customerList) {
for (APEX_Customer__c objCustomer: customerList) {

if (objCustomer.APEX_Customer_Status__c == 'Active' &&
trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {

// condition to check the old value and new value
APEX_Invoice__c objInvoice = new APEX_Invoice__c();
objInvoice.APEX_Status__c = 'Pending';
InvoiceList.add(objInvoice);
}
}
insert InvoiceList; // DML to insert the Invoice List in SFDC
}

// Method to update the invoice records
public static updateCustomerDescription (List<apex_customer__c>
customerList, Map<id, apex_customer__c> newMapVariable) {
List<apex_customer__c> customerListWithInvoice = [SELECT id,
Name,(SELECT Id, Name, APEX_Description__c FROM APEX_Invoice__r) FROM
APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];

// Query will be for only one time and fetches all the records
List<apex_invoice__c> invoiceToUpdate = new
List<apex_invoice__c>();

for (APEX_Customer__c objCust: customerList) {
for (APEX_Invoice__c objInv: invList) {
objInv.APEX_Description__c = 'OK To Pay';
invoiceToUpdate.add(objInv);
// Add the modified records to List
}
}
update invoiceToUpdate;
}
}

DML Bulk Calls

This example shows the Bulk trigger along with the trigger helper class pattern. You must save the helper class first and then save the trigger.
Note − Paste the below code in ‘CustomerTriggerHelper’ class which we have created earlier.

// Helper Class
public class CustomerTriggerHelper {
public static void isAfterUpdateCall(List<apex_customer__c> customerList,
Map<id, apex_customer__c> mapIdToCustomers, Map<id, apex_customer__c>
mapOldItToCustomers) {
createInvoiceRecords(customerList, mapOldItToCustomers); //Method call
updateCustomerDescription(customerList,mapIdToCustomers,
mapOldItToCustomers);
}

// Method To Create Invoice Records
public static void createInvoiceRecords (List<apex_customer__c>
customerList, Map<id, apex_customer__c> mapOldItToCustomers) {
List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
List<apex_customer__c> customerToInvoice = [SELECT id, Name FROM
APEX_Customer__c LIMIT 1];

for (APEX_Customer__c objCustomer: customerList) {
if (objCustomer.APEX_Customer_Status__c == 'Active' &&
mapOldItToCustomers.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
//condition to check the old value and new value
APEX_Invoice__c objInvoice = new APEX_Invoice__c();
objInvoice.APEX_Status__c = 'Pending';
objInvoice.APEX_Customer__c = objCustomer.id;
InvoiceList.add(objInvoice);
}
}
system.debug('InvoiceList&&&'+InvoiceList);
insert InvoiceList;
// DML to insert the Invoice List in SFDC. This also follows the Bulk pattern
}

// Method to update the invoice records
public static void updateCustomerDescription (List<apex_customer__c>
customerList, Map<id, apex_customer__c> newMapVariable, Map<id,
apex_customer__c> oldCustomerMap) {
List<apex_customer__c> customerListWithInvoice = [SELECT id,
Name,(SELECT Id, Name, APEX_Description__c FROM Invoices__r) FROM
APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];

// Query will be for only one time and fetches all the records
List<apex_invoice__c> invoiceToUpdate = new List<apex_invoice__c>();
List<apex_invoice__c> invoiceFetched = new List<apex_invoice__c>();
invoiceFetched = customerListWithInvoice[0].Invoices__r;
system.debug('invoiceFetched'+invoiceFetched);
system.debug('customerListWithInvoice****'+customerListWithInvoice);

for (APEX_Customer__c objCust: customerList) {
system.debug('objCust.Invoices__r'+objCust.Invoices__r);
if (objCust.APEX_Active__c == true &&
oldCustomerMap.get(objCust.id).APEX_Active__c == false) {
for (APEX_Invoice__c objInv: invoiceFetched) {
system.debug('I am in For Loop'+objInv);
objInv.APEX_Description__c = 'OK To Pay';
invoiceToUpdate.add(objInv);
// Add the modified records to List
}
}
}
system.debug('Value of List ***'+invoiceToUpdate);
update invoiceToUpdate;
// This statement is Bulk DML which performs the DML on List and avoids
// the DML Governor limit
}
}

// Trigger Code for this class: Paste this code in 'Customer_After_Insert'
// trigger on Customer Object
trigger Customer_After_Insert on APEX_Customer__c (after update) {
CustomerTriggerHelper.isAfterUpdateCall(Trigger.new, trigger.newMap,
trigger.oldMap);
// Trigger calls the helper class and does not have any code in Trigger
}

Other Salesforce Governor Limits

Following table lists down the important governor limits.

Description Limit
Total heap size 6 MB/12 MB
Total number of DML statements issued 150
Total number of records retrieved by a single SOSL query 2000
Total number of SOSL queries issued 20
Total number of records retrieved by Database.getQueryLocator 10000
Total number of records retrieved by SOQL queries 50000

So, this brings us to the end of blog. This Tecklearn ‘Understanding Governor Limits in Salesforce Apex’ blog helps you with commonly asked questions if you are looking out for a job in Salesforce. If you wish to learn Salesforce and build a career in Salesforce domain, then check out our interactive, Salesforce Certification Training: Admin 201 and App Builder, that comes with 24*7 support to guide you throughout your learning period. Please find the link for course details:

Salesforce Certification Training: Admin 201 and App Builder

Salesforce Certification Training: Admin 201 and App Builder

About the Course

Salesforce Certification Training course will help you pass the Salesforce Administrator Exam (Admin 201) and the Salesforce App Builder (Dev 401) Exam. Concepts on Force.com Platform, AppExchange, SFDC Security Model, Service Cloud, Sales Cloud, Lightning App Builder, Salesforce Reports & Dashboard can be mastered in this Salesforce Training course. You can also configure the platform, manage users, find better ways to use the platform’s features, build applications with Salesforce Lightning, and more. Further, in this Salesforce certification training course, you will master App builder, Apex, Visualforce, etc.

Why Should you take Salesforce Admin 201 and App Builder Training?

• As per Indeed.com data, 200% global jump in Salesforce jobs since Jan 2016. Salesforce Certified Administrators earn an annual average salary of $87,000 but can go as high as $160,000 depending on their knowledge, skills, and experience.
• More than 200,000 companies worldwide use Salesforce platform. Salesforce leads the CRM market with 19.5 percent of market share – Forbes.
• The global CRM software market will reach US$40.26 billion in 2023, up from US$36.9 billion (2020) – Statista.

What you will Learn in this Course?

Salesforce Fundamentals
• Introduction to CRM concepts and Cloud computing
• Salesforce.com Overview and Fundamentals
• Understanding Salesforce Platform
Understanding Salesforce Platform
• Understanding Salesforce Terminologies and Introducing the force.com platform
• Understanding Salesforce Metadata and API
• Describe the capabilities of the core CRM objects in the Salesforce schema
• Identify common scenarios for extending an org using the AppExchange
• About Salesforce Certification
Introduction to Sales Cloud
• Sales Cloud
• Sales Process
• Sales Productivity Features
• Lead Management
• Lead auto response
• Lead assignment
• Web to lead
• Accounts and Contacts Management
• Opportunities
• Campaign Management
Security Model, User Management and Its Features
• Security Model Mind Map
• System Level or Org Level Security
• User Administration and Troubleshooting
• Permission Sets
• Profile Management
• User Actions
• Assigning Permission
• Session settings
• Activations
• Page layout assignment
• Tab setting
• Field level security
Object, Record and Field Level Features
• Custom Object
• Custom Field
• Data Types
• Relationship among Objects
• Working with App and Tabs
Data Handling and Processing
• Data Import and Export with Salesforce
• Insert, Update and Delete Data with Salesforce
• Export Data with UI
• Export Data using Data Loader Tool
Deployment
• SandBox
• Moving Data from SB to Production – Deployment
• Types of SandBox
• Change Sets
• Types of Change Sets
Application Cycle
• Milestones
• Sandboxes
• Change Sets
• Packages
Reports and Dashboards
Declarative Implementation in Salesforce
Salesforce Development and Apex Programming
• Apex Programming
• Apex Classes
• Apex Settings
• SOQL – Salesforce Object Query Language
• DML Commands
• Apex Class in Detail
• Apex Triggers
• Apex Testing
• Access Specifier in Salesforce
• Testing
Lightning in Salesforce
• Lightning Components
• Lightning Component Capabilities
• Lightning Components vs. Visualforce
Visual Force in Salesforce
• Standard Visualforce controller and controller extensions,
• Visualforce Page
• Understanding the MVC Pattern
• Tools for Visualforce Development
• Visual Force Components
WorkFlows in Salesforce
• Work Flows in Salesforce
• Types of Work Flows
• Work Flows Rules
About Preparation of Salesforce 201 and App Builder Certification exams

Got a question for us? Please mention it in the comments section and we will get back to you.

 

0 responses on "Understanding Governor Limits in Salesforce Apex"

Leave a Message

Your email address will not be published. Required fields are marked *