Mastering Salesforce Governor Limits and Performance Optimization — Apex Part 14

Mohammad Usman
5 min readMar 17, 2024

--

Salesforce is a powerful platform for building enterprise applications, allowing organizations to manage their customer relationships, streamline business processes, and drive growth. However, as with any platform, Salesforce has its limitations, known as governor limits, which are in place to ensure the efficient and reliable operation of the platform. Understanding these limits and implementing strategies for optimizing code can significantly enhance the performance and scalability of your Salesforce applications.

In this comprehensive guide, we’ll explore Salesforce governor limits in detail, delve into strategies for optimizing Apex code to work within these limits, and discuss techniques for monitoring and troubleshooting performance issues.

Understanding Salesforce Governor Limits

What are Governor Limits?

Governor limits are runtime constraints enforced by the Salesforce platform to prevent code from consuming excessive resources, such as CPU time, memory, or database resources. These limits are in place to ensure fair resource allocation and maintain the overall stability and performance of the platform.

Types of Governor Limits

Salesforce imposes various types of governor limits, including:

1. Per-Transaction Limits: These limits apply to a single transaction or request, such as CPU time, heap size, and DML (Data Manipulation Language) statements.

2. Per-Execution Context Limits: These limits apply to the execution context of a single Apex transaction, including governor limits for SOQL (Salesforce Object Query Language) queries, SOSL (Salesforce Object Search Language) queries, and DML statements.

3. Per-User Limits: These limits are enforced on a per-user basis and include concurrent long-running requests, API requests, and SOQL queries.

4. Per-Organization Limits: These limits are enforced across the entire Salesforce organization and include limits on the number of concurrent Apex executions, future method executions, and async Apex jobs.

Example of Governor Limits

Let’s consider an example to illustrate how governor limits work:

public class GovernorLimitExample {
public void performDmlOperations() {
List<Account> accounts = new List<Account>();
for (Integer i = 0; i < 1000; i++) {
accounts.add(new Account(Name = ‘Account ‘ + i));
}
insert accounts; // DML statement

List<Contact> contacts = new List<Contact>();
for (Integer i = 0; i < 1000; i++) {
contacts.add(new Contact(FirstName = ‘John’, LastName = ‘Doe’));
}
insert contacts; // DML statement
}
}

In this example, we have a method `performDmlOperations()` that inserts 1000 Account records followed by 1000 Contact records. However, Salesforce imposes a limit of 150 DML statements per transaction. If this method is called within a single transaction, it will exceed the governor limit, resulting in a runtime exception.

Strategies for Optimizing Apex Code

To ensure that your Apex code operates efficiently within Salesforce governor limits, it’s essential to follow best practices and employ optimization strategies. Here are some techniques for optimizing Apex code:

Bulkify Your Code

One of the most crucial optimization techniques in Salesforce is bulkifying your code. Bulkification involves designing your code to operate efficiently with collections of records rather than individual records. This minimizes the number of DML statements, queries, and loops, thus reducing resource consumption and improving performance.

public class BulkifyExample {
public void performBulkDmlOperation(List<Account> accounts) {
List<Contact> contacts = new List<Contact>();
for (Account acc : accounts) {
contacts.add(new Contact(FirstName = ‘John’, LastName = ‘Doe’, AccountId = acc.Id));
}
insert contacts; // Bulk DML operation
}
}

In this example, instead of inserting Contact records individually within a loop, we collect all the Contact records into a list and perform a single bulk DML operation, thus optimizing the code for efficiency.

Efficient Querying

Minimize the number of SOQL queries and optimize existing queries to retrieve only the necessary fields and records. Additionally, leverage relationships and join queries to fetch related records efficiently.

public class QueryOptimizationExample {
public List<Account> getAccountsByOwner(String ownerId) {
return [SELECT Id, Name FROM Account WHERE OwnerId = :ownerId LIMIT 100];
}
}

In this example, we retrieve Account records owned by a specific user and limit the number of records returned to 100 to prevent hitting the governor limit for query rows.

Use Limits Methods

Salesforce provides methods such as `Limits.getLimitXXX()` and `Limits.getUsageXXX()` to programmatically access and monitor governor limits within your code. These methods allow you to proactively manage resource usage and avoid exceeding limits.

public class LimitsExample {
public void checkLimits() {
Integer queryLimit = Limits.getLimitQueries();
Integer queryUsage = Limits.getQueries();
System.debug(‘Query Limit: ‘ + queryLimit);
System.debug(‘Query Usage: ‘ + queryUsage);
}
}

In this example, we retrieve the current and maximum query limits and log them for monitoring purposes.

Cache Data Where Possible

Reduce the number of redundant queries and computations by caching frequently accessed data in memory or using platform caching mechanisms such as Platform Cache or External Cache. This improves performance and reduces the load on Salesforce resources.

public class DataCachingExample {
public static Map<Id, Account> accountCache = new Map<Id, Account>();

public static Account getAccountById(Id accountId) {
if (!accountCache.containsKey(accountId)) {
accountCache.put(accountId, [SELECT Id, Name FROM Account WHERE Id = :accountId]);
}
return accountCache.get(accountId);
}
}

In this example, we cache Account records in a map to avoid querying the database multiple times for the same record.

Monitoring and Troubleshooting Performance Issues

Even with optimized code, performance issues may still arise in Salesforce applications. Monitoring and troubleshooting these issues are essential for maintaining optimal performance. Here are some strategies for monitoring and troubleshooting performance issues:

Salesforce Inspector

Utilize tools like Salesforce Inspector, a Chrome extension that provides real-time insights into Salesforce governor limits, SOQL queries, and performance metrics. It allows developers to analyze code execution, identify bottlenecks, and optimize performance.

Debug Logs

Enable debug logging for specific users or transactions to capture detailed information about code execution, database operations, and governor limit usage. Analyze debug logs to identify performance bottlenecks and optimize code accordingly.

Performance Monitoring

Implement custom performance monitoring solutions using Salesforce features such as Platform Events, Custom Objects, and Apex triggers to track performance metrics, monitor resource usage, and receive alerts for potential issues.

Profiling Tools

Leverage profiling tools like Salesforce Optimizer and Apex Replay Debugger to analyze code performance, identify inefficiencies, and optimize critical areas of your Salesforce application.

Performance Tuning

Regularly review and fine-tune your Salesforce configuration, data model, and Apex code to optimize performance, reduce resource consumption, and ensure scalability as your application grows.

Resources for Further Learning

To further enhance your understanding of advanced Apex features and Salesforce development in general, here are some recommended resources:

- Salesforce Apex Developer Guide: The official Apex developer guide provides comprehensive documentation and examples for mastering Apex programming.
- Trailhead: Salesforce’s interactive learning platform offers a wide range of modules and trails on Apex development, asynchronous processing, integrations, and more.
- Salesforce Developer Blog: Stay updated with the latest news, tips, and best practices from Salesforce developers and experts through the official developer blog.
- Stack Exchange — Salesforce: Engage with the Salesforce community, ask questions, and share knowledge on Stack Exchange’s dedicated Salesforce platform.

Conclusion

Mastering Salesforce governor limits and performance optimization is crucial for building efficient, scalable, and high-performing applications on the Salesforce platform. By understanding the various types of governor limits, implementing optimization strategies, and employing monitoring and troubleshooting techniques, developers can overcome limitations, maximize resource utilization, and deliver exceptional user experiences.

--

--

Mohammad Usman

Trailblazer | Transforming Businesses through Salesforce Expertise | Salesforce Technical Architect, Consultant & Developer | Technical Lead