Salesforce Coding Best Practices 2025

Table Of Contents
- Follow Consistent Naming Conventions
- Use Bulkification in Triggers
- Use Custom Settings and Custom Metadata Types
- Use Platform Events for Asynchronous Processing
- Optimize Apex Code for Performance
- Handle Exceptions Properly
- Use the “with sharing” Keyword
- Use Efficient Data Structures
When it comes to Salesforce Coding Best Practices 2025, staying updated with the latest industry standards is crucial for any Salesforce developer aiming to excel in their career. In interviews, I have often faced questions that test my ability to write clean, efficient, and scalable code within Salesforce’s complex environment. Questions on optimizing Apex triggers, adhering to governor limits, and ensuring code maintainability are commonly asked. Hiring managers are keen to see how well I understand modular code design, exception handling, and security protocols. These are the very aspects that can make or break a Salesforce implementation, and mastering them is key to standing out in any interview.
CRS Info Solutions offers a comprehensive Salesforce course designed for beginners who want to dive into the world of Salesforce. This real-time training is tailored to provide practical skills, hands-on experience, and an in-depth understanding of Salesforce concepts. As part of the Salesforce training in Pune, participants will have access to daily notes, video recordings, interview preparation, and real-world scenarios to enhance their learning experience. Enroll today for a free demo!
This content is designed to help me prepare for those challenging interview questions by providing a deep dive into the best coding practices that align with Salesforce’s 2025 guidelines. It offers actionable insights into structuring my code, improving performance, and following security best practices that are critical in today’s Salesforce development landscape. By the end of this guide, I will be equipped with the knowledge to confidently tackle questions on coding practices, impress interviewers with my expertise, and demonstrate that I’m up-to-date with the latest Salesforce trends and standards.
See also: Salesforce SOQL and SOSL Interview Questions
1. Follow Consistent Naming Conventions
Consistent naming conventions help in understanding and maintaining code. When naming classes, methods, variables, and parameters consistently, team members can quickly understand the purpose of the code and avoid errors due to ambiguity.
How to apply:
- Classes and Triggers: Use camelCase or PascalCase.
Example:AccountHandler
(for a class) orhandleAccountCreation
(for a method). - Variables and Parameters: Use descriptive names that indicate their role.
Example:accountType
instead ofa
.
Code Example:
public class AccountHandler {
public void createAccount(String name, String type) {
Account acc = new Account(Name = name, Type = type);
insert acc;
}
}
Explanation:
The class name AccountHandler
clearly indicates the purpose of handling accounts. Method names follow camelCase, which is easy to read and understand. Variable names (name
, type
) clearly reflect their role in the method.
2. Use Bulkification in Triggers
Bulkification is the practice of ensuring that your code can handle multiple records at once without exceeding Salesforce’s governor limits. Salesforce imposes limits on the number of records processed in a single transaction, and bulkified code avoids hitting these limits.
How to apply:
- Always process records in bulk, even when you’re only dealing with one record at a time.
- Never use SOQL or DML inside loops.
Code Example:
trigger AccountTrigger on Account (before insert, before update) {
List<Account> accountsToUpdate = new List<Account>();
for (Account acc : Trigger.new) {
if (acc.Name == 'Acme') {
acc.Type = 'Prospect';
accountsToUpdate.add(acc);
}
}
update accountsToUpdate;
}
Explanation: Instead of updating records inside the loop, the code bulk processes records and updates them in batches to avoid hitting limits.
3. Avoid SOQL or DML in Loops
Salesforce imposes governor limits, and running SOQL queries or DML operations inside loops can easily exceed those limits. It’s critical to minimize the number of times these operations are executed, especially when dealing with large datasets.
How to apply:
- Always place SOQL queries and DML statements outside loops.
- Query once, loop over the result, and perform DML operations afterward.
Code Example:
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Type = 'Prospect'];
for (Account acc : accounts) {
acc.Name = acc.Name + ' - Updated';
}
update accounts;
Explanation:
Here, SOQL is executed once before the loop starts, and the DML operation (update accounts
) is done after the loop, thus preventing excessive calls to the database and reducing the chances of hitting governor limits.
See also: Salesforce JavaScript Developer Interview Questions
4. Use Custom Settings and Custom Metadata Types
Custom Settings and Custom Metadata Types allow you to store configuration data that can be accessed programmatically. This approach helps to avoid hardcoding values and allows the application to be more dynamic and easier to maintain.
How to apply:
- Use Custom Settings for data that can be set at the org level and doesn’t change often.
- Use Custom Metadata Types for configuration data that can be deployed across environments.
Code Example:
CustomSetting__c settings = CustomSetting__c.getInstance('MyConfig');
String apiUrl = settings.Api_URL__c;
Explanation:
This code fetches configuration from a Custom Setting, making the URL dynamic. You can change the value in the Salesforce UI without needing to modify the code, which is ideal for environments with frequent changes or different deployment configurations.
5. Write Tests with Adequate Coverage
Testing is crucial for ensuring that your code works as expected and for maintaining code quality. Writing tests with 75% or more coverage helps detect issues early, facilitates code reviews, and ensures that the code performs under different conditions.
How to apply:
- Write test classes for every piece of functionality.
- Test both positive (happy path) and negative (error scenarios) cases.
- Always use
System.assert
to verify that the outcome is as expected.
Code Example:
@isTest
private class AccountHandlerTest {
@isTest static void testCreateAccount() {
AccountHandler handler = new AccountHandler();
handler.createAccount('Test Account', 'Customer');
Account acc = [SELECT Name, Type FROM Account WHERE Name = 'Test Account'];
System.assertEquals('Customer', acc.Type);
}
}
Explanation:
This test ensures that the createAccount
method creates an account with the correct Type
. The System.assert
statement verifies that the actual result matches the expected outcome, ensuring the functionality works as expected.
See also: Salesforce Admin Interview Questions
6. Use Platform Events for Asynchronous Processing
Platform Events allow you to implement event-driven architectures in Salesforce. They decouple processes and handle asynchronous tasks efficiently, improving scalability and performance.
How to apply:
- Publish events from Apex, and have external systems subscribe to those events.
- Use Platform Events when you need to trigger actions in other systems or workflows asynchronously.
javaCopy code// Publishing Platform Event
MyEvent__e event = new MyEvent__e(Message__c = 'Hello World');
Database.SaveResult result = EventBus.publish(event);
MyEvent__e event = new MyEvent__e(Message__c = 'Hello World');
Database.SaveResult result = EventBus.publish(event);
Explanation:
Here, a Platform Event
is published with a message. This event could be picked up by a Lightning Component, external system, or another Apex class to trigger further processing. This decouples components, which helps with scalability and system flexibility.
7. Limit Query Results
Using LIMIT
ensures that your queries return only the necessary records, which is important for performance and avoiding governor limits. It also prevents retrieving unnecessary data when you only need a subset of results.
How to apply:
- Always limit the number of records returned in a query when possible.
- Be mindful of querying for more data than necessary.
Code Example:
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Type = 'Prospect' LIMIT 100];
Explanation:
The query limits the results to 100 records. This is a good practice when you expect only a small subset of data and want to avoid unnecessary overhead and performance issues.
See also: Salesforce Admin Interview Questions
8. Optimize Apex Code for Performance
Optimizing Apex code improves its execution time and memory usage, ensuring it can handle large datasets and high volumes of transactions efficiently.
How to apply:
- Use efficient algorithms.
- Avoid repetitive calculations or queries inside loops.
Code Example:
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Type = 'Prospect'];
for (Account acc : accounts) {
acc.Name = acc.Name.toUpperCase();
}
update accounts;
Explanation:
This code performs string manipulation after retrieving the data, rather than doing it inside a loop with queries. It avoids unnecessary operations that could degrade performance.
See also: Salesforce Pardot Interview Questions
9. Handle Exceptions Properly
Exception handling prevents code from failing silently and allows you to log or respond to errors in a structured manner. Proper error handling ensures that users get meaningful error messages and the system behaves predictably.
How to apply:
- Use
try-catch
blocks to capture exceptions. - Log or send error messages to developers for further investigation.
Code Example:
try {
insert new Account(Name = 'Test Account');
} catch (DmlException e) {
System.debug('Error: ' + e.getMessage());
}
Explanation:
This block catches any DmlException
(e.g., if the record fails to insert) and logs the error message for troubleshooting, ensuring the application continues running smoothly.
10. Use @AuraEnabled for Lightning Components
When building Lightning components, using the @AuraEnabled
annotation ensures that Apex methods can be called from the Lightning components, enabling seamless integration between front-end and back-end logic.
How to apply:
- Mark Apex methods with
@AuraEnabled
to expose them to Lightning Components. - Use
@AuraEnabled(cacheable=true)
to cache results and improve performance for read-only data.
Code Example:
public with sharing class AccountController {
@AuraEnabled(cacheable=true)
public static Account getAccount(String accountId) {
return [SELECT Id, Name FROM Account WHERE Id = :accountId LIMIT 1];
}
}
Explanation:
This Apex method is exposed to Lightning components with @AuraEnabled
, allowing it to be called by a component. The cacheable=true
improves performance by caching results, reducing the need for repetitive queries.
11. Use Named Credentials for External Calls
Using Named Credentials securely stores the authentication data for external services, preventing hardcoding of sensitive information such as usernames and passwords.
How to apply:
- Configure Named Credentials in Salesforce Setup to securely store authentication data.
- Use the
callout:
prefix in your Apex code to make HTTP requests.
Code Example:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:MyNamedCredential/endpoint');
req.setMethod('GET');
HttpResponse res = new Http().send(req);
Explanation:
This code sends a GET request to an external system using a Named Credential. By using Named Credentials, sensitive information like API keys are securely stored and not exposed in the code.
See also: Salesforce OWD Interview Questions and Answers
12. Use the “with sharing” Keyword
By default, Apex classes run in “without sharing” mode, which means they can access all records, regardless of the user’s sharing rules. The with sharing
keyword ensures that your Apex code respects the current user’s sharing rules, promoting data security.
How to apply:
- Always use
with sharing
unless there is a specific reason to bypass sharing rules.
Code Example:
public with sharing class AccountController {
public Account getAccount(String accountId) {
return [SELECT Id, Name FROM Account WHERE Id = :accountId];
}
}
Explanation:
The with sharing
keyword ensures that the code respects the user’s data access rights. It prevents unauthorized users from accessing records they shouldn’t have access to.
13. Minimize Use of Static Variables in Triggers
Static variables in triggers can persist between trigger invocations, which can lead to unexpected behavior or errors, especially if data is processed incorrectly. Minimizing their use helps ensure proper processing in bulk trigger contexts.
How to apply:
- Use static variables sparingly in triggers.
- Ensure that state is not being shared across different trigger executions.
Code Example:
public class AccountTriggerHandler {
public static Integer triggerCounter = 0;
public static void handleAccountTrigger(List<Account> newAccounts) {
triggerCounter++;
// Avoid using static variables across multiple trigger invocations
}
}
Explanation:
Here, the static variable triggerCounter
tracks the number of times a trigger is fired, but its use can lead to data inconsistencies. Ideally, such tracking should be done in a more robust way to prevent problems in bulk trigger scenarios.
See also: Accenture LWC Interview Questions
14. Avoid Hardcoding IDs
Hardcoding Salesforce record IDs (like record types or field IDs) creates code that is not portable across different Salesforce environments (e.g., from Sandbox to Production). It’s best practice to query these values dynamically.
How to apply:
- Query for IDs dynamically instead of hardcoding them.
Code Example:
Id recordTypeId = [SELECT Id FROM RecordType WHERE SObjectType = 'Account' AND DeveloperName = 'Customer_Record_Type' LIMIT 1].Id;
Explanation:
This code dynamically fetches the Record Type ID for an “Account” object, based on the developer name. This avoids the need to hardcode the ID, making the code environment-agnostic.
See also: Salesforce Developer interview questions for 5 years experience
15. Use Efficient Data Structures
Using efficient data structures like maps and sets ensures faster data processing. Maps provide constant time lookups, and sets are useful for ensuring uniqueness and speeding up membership tests.
How to apply:
- Use
Map
when you need to quickly access values based on keys. - Use
Set
when you need to track unique values.
Code Example:
Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Type = 'Prospect']);
Set<String> accountNames = new Set<String>(accountMap.keySet());
Explanation:
The Map<Id, Account>
structure allows for fast lookups of Account
objects by ID. The Set<String>
helps store the unique names of accounts. Both structures ensure more efficient data processing when working with large volumes of records.
Why Salesforce is a Must-Learn Skill in Pune?
Pune has secured its place as a major player in India’s IT sector, attracting multinational corporations and creating a continuous need for skilled professionals. Salesforce CRM, being one of the most popular platforms, is central to this growing demand. Our Salesforce training in Pune provides a unique opportunity to tap into the city’s thriving job market. Leading companies such as Deloitte, Accenture, Infosys, TCS, and Capgemini are consistently in search of certified Salesforce experts. These organizations rely on professionals skilled in Admin, Developer (Apex), Lightning, Salesforce Marketing Cloud, CPQ, and Integration to efficiently manage and optimize our Salesforce environments.
The demand for certified Salesforce professionals is growing rapidly, and they enjoy highly competitive salaries in Pune. Salesforce developers and administrators in the city benefit from some of the best pay packages in the tech industry, making Salesforce a valuable and promising skill. Earning your Salesforce certification from a reputable training institute will significantly improve your chances of landing high-paying roles and boosting your career trajectory.
Why Choose CRS Info Solutions in Pune?
CRS Info Solutions is one of the premier institutes offering Salesforce training in Pune. We provide a comprehensive curriculum that covers Salesforce Admin, Developer, Integration, Marketing Cloud, CPQ, and Lightning Web Components (LWC). Our expert instructors offer not just theoretical lessons, but also practical, hands-on experience to prepare you for real-world challenges. At CRS Info Solutions, we are dedicated to helping you become a certified Salesforce professional, ready to embark on a rewarding career. Our well-rounded approach ensures that you meet the requirements of top companies in Pune. Begin your journey today and become a certified Salesforce expert. Enroll now for a free demo at CRS Info Solutions.