How to cache retrieved records in Apex?


Imagine you are developing a new project from scratch. The project is getting bigger over time, due to increasingly complex logic, multiple Apex Triggers, Queueables and so on. At some point you are getting “LimitException: Too many SOQL queries: 101” exception. Crap, so what next? You have to go through all the classes to refactor the code and remove the redundant SOQL queries. After couple of hours you found only a few of them so sooner or later the problem comes back like a boomerang. Sounds like a nightmare? What if there is a better approach, like cache retrieved from Salesforce database records in Apex?


What you need is to create a DAO class for an object, with a static map for retrieved records, method to get records from SF database and logic to check if records are already retrieved. Still unconvinced? Let’s take a look at my approach:

public with sharing class AccountDao {

    private static Map<Id, Account> cachedAccountsByIds = new Map<Id, Account>();
    public static List<Account> findByIds(List<Id> ids) {
        Boolean newAccountLoadNeeded = false;
        for (Id accountId : ids) {
            if (!cachedAccountsByIds.containsKey(accountId)) {
                newAccountLoadNeeded = true;
        if (newAccountLoadNeeded) {
                    SELECT Name, Phone, BillingPostalCode 
                    FROM Account 
                    WHERE Id IN :ids
        return cachedAccountsByIds.values();

The first time the method will retrieve records from the Salesforce database and cache them into the static map. If you need these records again during the transaction, you won’t need additional SOQL query, because you will get it from the map. Clever, right?

Was it helpful? Check out our other great posts here.


5 1 vote
Article Rating
Notify of
1 Comment
Oldest Most Voted
Inline Feedbacks
View all comments
Scott Gibson
Scott Gibson
1 year ago

The solution doesn’t seem to be coming up on mobile!

Close Menu
Would love your thoughts, please comment.x