Apex Best Practices – Avoid Exceeding Governor Limits

Apex Code is the Force.com programming language used by developers to build custom business logic on the platform by writing Apex Triggers, custom VisualForce controllers and extensions, Anonymous Apex codes, etc. It runs in a multi-tenant environment where a single resource can be shared by all different Salesforce organisations or instances. In this case, it is crucial to ensure that no organisation would monopolise the resources. Salesforce.com enforced a set of restrictions or limits to ensure the efficient use of resources in the force.com platform. These governor execution limits are applied per transaction basis, and when crossed, throws an error and halts the execution of the program.

As a developer, it is significant to ensure that our codes are scalable and can prevent the enforced limits. This article illustrates some of the key best practices for writing and designing Apex Code solutions on the Force.com platform. There are a lot of enforced limits by the platform, and here are some tips on how to avoid the most common limits exceeded by developers:

1. Avoiding SOQL queries and DML Calls in For Loops

The limits allow only 100 SOQL queries and 150 DML operations maximum per transaction otherwise it will throw an error. In the example below, a query was initiated inside the for loop [1.1]. In this case, if the trigger is initiated with more than 100 records, it will exceed the governor limits. The UPDATE DML call was also initiated inside the for loops [1.2]. In this case, if the records gathered are more than 150, it will breach the governor limits.

1.1 to 1.2 - Not optimised code

To avoid these governor limits to throw an error, we should ensure that queries are initiated outside the for loops [1.3], optimise the code by bulkifying it [1.4] to efficiently query the contacts and only perform a single update DML operation [1.5].

1.3 to 1.5 - Optimised code

2. Adding filters to SOQL queries

The limits allow only 50,000 or less than 50,000 records retrieved by SOQL queries per transaction otherwise it will throw an error. If the records retrieved are more than 50,000, it may breach the limit [2.1]. In this case, we can utilise logical conditions to filter our records [2.2].

2.1 - For loop without filters

2.2 - For loop with filters

3. Looping through large sets of data

Returning large set of queries may cause the exceeding of the heap limit [3.1]. In this case, a SOQL query in a for loop should be used instead [3.2]. In this case, it can process multiple batches of records through the use of internal calls to query and queryMore.

3.1 - Querying large sets of data

3.2 - Looping through large sets of data

To view the full set of execution governors and limits, you may access it here - Execution Governors and Limits.

              LEARN MORE

What Certification are you studying for now?

Focus on Force currently provides practice exams and study guides for ten certifications

Comments

  1. Aleksandrs

    List accs = new List;
    for (list acc : [select id from acc])
    accs,add(acc);

    even if im trying to query 50k records, is it better to do it the above way? Not this way – list accs = [select id from acc] ?

    1. Martin Gessner

      Hi Aleksandrs,

      There are 3 common collections types we can use to process your data – List, Set and Map. If you wish to store a list of Ids alike to your example above, you can use Set. A set is an unordered collection of elements that do not contain any duplicates. (Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections.htm)

      Set accountIds = new Set();
      for(Account acc: [SELECT Id from Account]){
      accountIds.add(acc.Id);
      }

      Let me know if you need more information.