Best Practices & Optimization Tips in Apex
Introduction
Apex is a powerful language, but it runs in a multi-tenant environment, where efficiency and scalability are crucial. Writing optimized and maintainable code not only prevents hitting governor limits but also improves application performance, reduces errors, and keeps your org clean and future-ready.
Following best practices helps you deliver secure, scalable, and efficient solutions that can handle large data volumes and complex business logic without failure.
Real-Life Analogy
Imagine you’re running a restaurant kitchen. If every chef grabs ingredients separately and cooks without coordination, it’s chaos — ingredients run out, time is wasted, and quality suffers.
But with best practices — bulk preparation, organized stations, and efficient tools — everything runs smoothly, even during rush hours.
The same applies to Apex: organized, reusable, and bulk-friendly code runs better and avoids system overload.
Key Best Practices & Tips
Category | Tip |
---|---|
Bulkification | Handle multiple records at once, avoid DML/SOQL in loops |
Governor Limits | Monitor and stay within Apex limits |
Code Reusability | Use methods and helper classes to reduce repetition |
Selective SOQL | Query only required fields with filters |
Trigger Framework | Use one trigger per object and delegate logic to handler classes |
Exception | Wrap risky code in try-catch blocks to handle errors |
Handling | gracefully |
Test Coverage | Write test classes with realistic data and cover all branches |
Avoid Hardcoding | Use Custom Labels, Custom Settings, and Custom Metadata |
Use Collections | Process data in Lists, Sets, and Maps instead of one-by-one |
Code Examples
1: Bulkified DML Operation
Bad Practice (DML in Loop):
for (Contact c : contactList) {
insert c; // BAD – uses 1 DML per record!
}
Good Practice (Bulk Insert):
insert contactList; // GOOD – single DML for all records
Output:
DML Statements Used: 1 (instead of 10 if done in a loop)
Code Explanation :
Inserting all records at once keeps you under the 150 DML statement limit.
2: Using Collections to Avoid Repeated SOQL
Inefficient:
for (Opportunity opp : oppList) {
Account acc = [SELECT Name FROM Account WHERE Id = :opp.AccountId]; // SOQL inside loop
}
Efficient:
Set<Id> accountIds = new Set<Id>();
for (Opportunity opp : oppList) {
accountIds.add(opp.AccountId);
}
Map<Id, Account> accMap = new Map<Id, Account>(
[SELECT Name FROM Account WHERE Id IN :accountIds]
);
for (Opportunity opp : oppList) {
Account acc = accMap.get(opp.AccountId);
}
Code Explanation :
• We collect all related Account IDs first.
• Then run one SOQL to get all needed Accounts.
• Finally, use a Map to retrieve accounts efficiently — saving SOQL calls.
Tasks For Practice
Task 1: Bulk Insert Contacts
Create a List<Contact> with at least 5 records.
Insert them all at once and print the number of DML statements used.
Task 2: Optimize SOQL Queries
You are given a list of Case records.
Query all their related Contact records using one SOQL, not one-per-loop.
Task 3: Implement Error Handling
Write a method that tries to update a Lead.
If an error occurs (e.g., invalid ID), catch the exception and print a custom error message.
Task 4: Avoid Hardcoding
Print a custom message using a Custom Label in Apex code instead of hardcoding the string.