@AuraEnabled and cacheable=true in Salesforce: Complete Guide for LWC Developers
- VlocityGru
- 2 days ago
- 4 min read
Updated: 1 day ago
Introduction
If you are building Lightning Web Components (LWC) or working with Vlocity OmniStudio, you have likely seen @AuraEnabled on Apex methods. But what exactly does it do — and what is the difference between @AuraEnabled and @AuraEnabled(cacheable=true)?
This guide breaks it down clearly: what each annotation means, when to use cacheable=true, what restrictions apply, and what interviewers are really asking when they bring this topic up.
What is @AuraEnabled in Salesforce Apex?
@AuraEnabled is an Apex annotation that exposes a method so it can be called from Lightning Web Components (LWC) or Aura components.
apex
@AuraEnabled
public static Account getAccount(Id accId) {
return [SELECT Id, Name FROM Account WHERE Id = :accId];
}Without @AuraEnabled, the method is invisible to the frontend:
Caller | Without @AuraEnabled | With @AuraEnabled |
LWC | ❌ Cannot call | ✅ Can call |
Aura Component | ❌ Cannot call | ✅ Can call |
OmniScript (via Apex Action) | ❌ Cannot call | ✅ Can call |
This annotation is the bridge between your Apex backend and your Lightning frontend. It is mandatory — no annotation, no access.
What Does cacheable=true Mean?
apex
@AuraEnabled(cacheable=true)
public static Account getAccount(Id accId) {
return [SELECT Id, Name FROM Account WHERE Id = :accId];
}Adding cacheable=true tells Salesforce:
"The result of this method can be stored temporarily on the client side and reused."
In practice, this means:
Salesforce stores the response in the client-side cache after the first call
If the same method is called again with the same parameters, the data may be returned from cache instead of hitting the server
This results in a faster UI and reduced server load
Benefits of cacheable=true
Faster UI rendering — no round-trip to the server on repeated calls
Reduced Apex execution — fewer governor limit concerns
Better user experience — especially on detail pages and read-heavy screens
The Most Important Rule: cacheable=true Is Read-Only Only
This is where most developers make mistakes.
cacheable=true can only be used when the Apex method is completely read-only - meaning it contains no DML operations whatsoever.
Allowed with cacheable=true ✅
@AuraEnabled(cacheable=true)
public static List<Contact> getContacts(Id accId) {
return [SELECT Id, Name, Email FROM Contact WHERE AccountId = :accId];
}NOT Allowed with cacheable=true ❌
@AuraEnabled(cacheable=true)
public static void updateAccount(Account acc) {
update acc; // ❌ Runtime error — DML not allowed with cacheable=true
}Forbidden DML operations with cacheable=true:
insert
update
delete
upsert
merge
undelete
If you include DML in a cacheable=true method, Salesforce throws a runtime error. It will not warn you at compile time — so test carefully.
Why cacheable=true Is Mainly Used in LWC
LWC re-renders frequently — when reactive properties change, when data refreshes, when navigation occurs. Without caching, every re-render could trigger a fresh Apex call.
cacheable=true is especially valuable for:
Detail pages — loading Account or Contact data
Search results — displaying filtered records
Lookup fields — fetching related records
Read-only dashboards — summarizing data
Using cacheable=true with @wire (Recommended Pattern)
import { LightningElement, wire } from 'lwc';
import getAccount from '@salesforce/apex/AccountController.getAccount';
export default class AccountDetail extends LightningElement {
@wire(getAccount, { accId: '$recordId' })
account;
}@wire requires the Apex method to have cacheable=true. If you try to wire a non-cacheable method, LWC will throw an error.
When NOT to Use cacheable=true
Avoid cacheable=true when:
The data changes frequently and you need fresh results every time
The method performs any DML (save, update, delete)
The method contains validation logic before a save
The method is part of a form submission or transactional flow
Using cacheable=true on methods that should return fresh data can cause stale data bugs that are very difficult to debug — the UI shows old data because it is pulling from cache.
OmniScript and cacheable=true — A Critical Distinction
This is a frequent interview topic for Vlocity / OmniStudio developers.
Question: Can you use cacheable=true for Apex called from OmniScript?
Answer: No.
Here is why:
OmniScript invokes Apex imperatively (not via @wire). More importantly, OmniScript flows are often transactional — they collect data across steps and submit it. In this context:
Cached data can become stale mid-flow
The user may see data from a previous session
Transactional integrity is compromised
Scenario | Use cacheable=true? |
LWC read-only data fetch | ✅ Yes |
LWC @wire call | ✅ Required |
LWC imperative save/update | ❌ No |
OmniScript Apex Action | ❌ No |
Integration Procedure Apex Step | ❌ No |
How Salesforce Caching Works (Simplified)
LWC calls an Apex method with cacheable=true
Apex executes and returns the result
Salesforce stores the response in the client-side Lightning Data Service cache
On the next call with the same parameters, the cached response is returned
The server is not contacted again (until the cache expires or is invalidated)
Important: You do not control the cache duration directly. Salesforce manages cache expiry. You can manually refresh cache in LWC using refreshApex() when needed.
import { refreshApex } from 'lightning/uiRecordApi';
// Call this to force a fresh server call
refreshApex(this.wiredResult);Interview-Ready Explanation
If an interviewer asks about @AuraEnabled(cacheable=true), here is a clear, concise answer:
"@AuraEnabled exposes an Apex method to LWC and Aura components. Adding cacheable=true enables client-side caching of the response, which improves performance by avoiding repeated server calls. It can only be used on read-only methods — any DML will cause a runtime error. It is required when using @wire in LWC, and should never be used with OmniScript Apex actions."
Quick Reference: Mental Model
cacheable=true → read-only + fast + @wire compatible
no cacheable → write / validate / save / OmniScriptSummary
@AuraEnabled is mandatory to expose Apex to LWC, Aura, or OmniScript
cacheable=true enables client-side caching for read-only methods
DML inside a cacheable=true method causes a runtime error
@wire in LWC requires cacheable=true
OmniScript Apex actions should never use cacheable=true
Use refreshApex() when you need to bypass cache and fetch fresh data

