You are here:
ApexGuru Antipatterns
The antipatterns highlighted in ApexGuru help you detect avoidable inefficiencies in your Apex code. Where practical, we also share recommendations for revising your approach to improve the efficiency of your code.
- ApexGuru Antipattern: Aggregating Records in Apex
SOQL queries that manually compute aggregate functions in Apex are inefficient and lead to performance issues. This approach wastes CPU resources and results in bloated, less readable code that's harder to maintain. Instead, use SOQL’s built-in aggregate functions like SUM(), AVG(), COUNT(), and COUNT_DISTINCT() to perform the work at the database level. - ApexGuru Antipattern: Busy Loop Delay
Busy loops that introduce a delay aren’t efficient and lead to performance issues. They waste CPU resources due to continuous loop execution. Governor limit breaches cause transaction failures. For delayed execution, use Salesforce alternatives like scheduling systems in Apex. If the delay is due to an async job, use System.enqueueJob with a delay parameter. - ApexGuru Antipattern: Copying List or Set Elements Using a For Loop
Using a For loop to copy parts of a list or set takes more CPU time and can cause governor limit breaches, especially with large datasets. Instead, Apex provides the addAll() method to copy elements efficiently in a single operation, improving both performance and code clarity. - ApexGuru Antipattern: DML in a Loop
Executing DML operations (insert, update, and delete) inside loops causes excessive resource consumption and can hit governor limits. Instead, batch DML operations by storing records in a list and performing the DML operation one time outside of the loop. - ApexGuru Antipattern: Expensive Debug Statements
Overusing System.debug() slows down execution, especially in production environments. Writing large amounts of data to logs increases the execution time and affects performance. Plus, the logs fill, making it harder to identify important issues. - ApexGuru Antipattern: Expensive Methods
Hot methods that consume over 5% of CPU time can cause performance bottlenecks, breach governor limits, and decrease system performance. Expensive methods consume more than 2% but less than 5% of CPU time. Critically expensive methods consume more than 5% of CPU time. To reduce CPU consumption, refactor expensive methods. - ApexGuru Antipattern: Expensive String Comparison
The == operator for string comparison invokes java.text.Collator.compare(), which is slower than using String.equals() or String.equalsIgnoreCase(). Longer strings and larger loops increase overhead. - ApexGuru Antipattern: Limits.getHeapsize() Methods
The Limits.getHeapSize() method monitors memory consumption during execution. This operation increases resource consumption, especially when used in production environments. When used in debug statements or logs, this method is evaluated even if the logs aren’t printed in production and this causes more performance degradation. - ApexGuru Antipattern: Redundant SOQL
Executing multiple SOQL queries on the same sObject with identical or nearly identical filter conditions creates inefficiencies. This practice wastes governor limits and increases transaction time because it requires more database round-trips. Processing separate query responses wastes CPU time and heap space. - ApexGuru Antipattern: Schema.getGlobalDescribe() Called Multiple Times Within a Class
Multiple calls to Schema.getGlobalDescribe() in a class cause performance issues and are computationally expensive. Calling this method multiple times within the same method results in redundant schema retrieval. Increased CPU usage can cause you to go over your governor limits. - ApexGuru Antipattern: Schema.getGlobalDescribe() In a Loop
The Schema.getGlobalDescribe() method collects schema information on all SObjects, which is computationally expensive. Using Schema.getGlobalDescribe() inside a loop can lead to performance issues, including breaking governor limits. - ApexGuru Antipattern: Schema.getGlobalDescribe() Not Efficient
Using Schema.getGlobalDescribe() to retrieve metadata for a single known SObject isn’t efficient. This method causes unnecessary overhead, decreases performance, and increases the latency of the associated entry point. - ApexGuru Antipattern: SObject Map in a For Loop
Building Map<Id, sObject> in a For loop inserts one record at a time. This query fetches all Custom Object__c records without filtering, which causes extra CPU usage. Filtering later in Apex boosts memory use, risks overflow, and slows performance. Instead, use Apex's map constructor or putAll(). - ApexGuru Antipattern: SOQL in a Loop
Executing SOQL queries inside loops can quickly exhaust the governor limits and decrease system performance. Salesforce enforces a limit on the number of queries per transaction. Instead, batch SOQL queries outside of loops. - ApexGuru Antipattern: SOQL in a Loop (One Hop)
The SOQL query is placed in a method in one class and the loop that invokes this method is in a different class. This structure leads to excessive SOQL queries, potentially hitting governor limits. Repeated query execution across class boundaries causes performance bottlenecks. Refactor the code to batch SOQL queries outside the loop, even if they’re spread across multiple classes. - ApexGuru Antipattern: SOQL with Apex Filter
Executing SOQL queries without a WHERE clause or LIMIT statement and filtering them in Apex retrieves unnecessary data. This process increases memory and CPU usage and can lead to overall system performance and governor limit issues. - ApexGuru Antipattern: SOQL with Negative Expressions
SOQL queries that use negative expressions such as NOT IN or != don't index effectively, leading to full-table scans. Less-efficient database operations increase query time and CPU usage. Avoid negative expressions. Use positive expressions wherever possible. - ApexGuru Antipattern: SOQL with Unused Fields
Retrieving unused fields in SOQL queries increases overhead, resource consumption, and query execution time. It also increases heap size and causes governor limits to be exceeded, especially with large datasets or complex objects. Only include fields directly required by your logic. Regularly review and improve SOQL queries to remove unused fields. - ApexGuru Antipattern: SOQL with Wildcard Filter
Using a wildcard such as LIKE '%term in SOQL queries prevents the use of indexes and causes full-table scans. Full-table scans increase query execution time and CPU usage. Use indexed fields for filtering and optimized search strategies. - ApexGuru Antipattern: SOQL Without a WHERE Clause or LIMIT Statement
Executing SOQL queries without a WHERE clause or LIMIT statement can retrieve too many records, leading to governor-limit breaches for the number of rows returned. To restrict the amount of data returned, include a WHERE clause or LIMIT statement in SOQL queries. - ApexGuru Antipattern: SOQL Without Platform Cache
Running the same SOQL query repeatedly during a transaction or across requests can slow down performance and put an unnecessary load on the database. Instead, use Platform Cache to eliminate the need for custom settings or persistent storage. - ApexGuru Antipattern: Sorting in Apex
Sorting records in Apex code uses more central processing unit (CPU) time and can exceed governor limits. This is especially true for large datasets. Using Apex to sort can also lead to heap-size overflows and degraded query performance. - ApexGuru Antipattern: Unused Methods
Unused Apex methods contribute to code bloat and increase the cognitive load for developers. These pieces of code make it harder to maintain the system and can also increase the size of the deployment package, making it more difficult to stay within the Salesforce Apex code size limits. Identify and remove unused methods to improve code clarity and performance.

