OmniStudio Cache Strategies
Use this skill when deciding whether, where, and how to cache an OmniStudio
read path — and when diagnosing a cache that appears configured but is not
changing anything. It covers the three distinct caches that share the word
"cache" in OmniStudio, the Platform Cache limits every one of them inherits,
and the security consequences of serving a payload that was computed for
somebody else.
Before Starting
- Which runtime is this org on? Standard runtime and the Vlocity managed
package have separate documentation, separate settings, and in places
separate behaviour.
OmniStudioSettings.enableStandardOmniStudioRuntime
(API 65.0+) and enableOaForCore (64.0+) answer the question. Most
published OmniStudio writing describes the package; assume nothing until
you have checked.
- Is Platform Cache actually allocated? A partition with no capacity
produces no error and no speedup. Verify allocation in Setup before
scheduling any tuning work.
- What is the freshness contract in business terms? Not "as fresh as
possible" — a number, agreed with whoever owns the data. The platform's
5-minute TTL floor means some answers rule caching out entirely.
- Who can reach this component? Internal only, authenticated portal, or
guest. The answer changes the cache type and may forbid caching outright.
The Three Caches
Naming the layer is the whole diagnostic. These are independent:
| Layer |
Stores |
Configured by |
Symptom when misconfigured |
| Component metadata cache |
the compiled component definition |
isMetadataCacheDisabled (boolean, default false — so it is on by default) on OmniIntegrationProcedure and OmniScript |
slow cold start after deploy |
| Response cache |
the output payload |
Data Mapper Options tab (Platform Cache Type, Time to Live in Minutes); IP Cache Configuration section (whole response) or Cache Block element (enclosed steps); responseCacheType in metadata, plus responseCacheTtlMinutes on the Data Mapper type only |
warm reads no faster than cold |
| Platform Cache |
the underlying key/value substrate |
Setup → Platform Cache partition allocation |
nothing is cached at all, silently |
isMetadataCacheDisabled is a negative. Default false means metadata
caching is already enabled; setting it true turns caching off. It is a
debugging lever, not a performance lever, and flipping it will not change what
a warm read returns.
The Limits That Decide The Design
Every OmniStudio response cache sits on Platform Cache and inherits its
bounds. These are the numbers that most often invalidate a proposed design:
| Constraint |
Value |
| TTL minimum (org and session) |
300 s / 5 minutes |
| TTL maximum — org cache |
172,800 s / 48 hours (default 86,400 s / 24 h) |
| TTL maximum — session cache |
28,800 s / 8 hours |
| Maximum cache key size |
50 characters |
| Cache key characters |
alphanumeric only — put() throws Cache.InvalidParamException otherwise |
| Maximum size of a single cached item |
100 KB |
| Minimum partition size |
1 MB |
| Maximum local cache per partition, per request |
500 KB session / 1,000 KB org |
Three consequences worth internalising:
- A freshness requirement tighter than 5 minutes is a decision not to
cache, not a smaller number in the TTL field.
- The Redis-style key
catalog:v2:region=NA is illegal on this platform.
Use camelCase with no separators.
- Caching the whole aggregate response usually exceeds 100 KB. Cache the
resolved decision instead.
Security Consequences Of A Warm Read
A cache hit returns a payload computed during somebody else's request, under
that request's permission evaluation. Two documented facts and one reported
behaviour follow:
- Documented. "Data in the cache isn't encrypted." Shield Platform
Encryption does not follow a value into a cache entry.
- Documented. Org cache is addressed by a key. If the key is derived from
caller-supplied inputs rather than a server-resolved subject, the
caller chooses which entry to read. On a guest-reachable page this is a
cross-tenant read.
- Reported, not documented. Metadata caching is reported to let a component
execute for a user who would fail its Required Permission check on a cold
run, because that check sits on the path the cache skips. Treat this as a
reason not to lean on Required Permission as your only authorization
boundary — not as a Salesforce-documented behaviour you can cite. See
gotchas.md §4 for the provenance.
The defensive posture the third bullet implies is sound regardless of whether
the specific bypass reproduces in your org: an access check that runs only on a
cold path is not an authorization boundary. Gate on the object and field
permissions of the running user and on the sharing model, which are evaluated
per call.
Keep fieldLevelSecurityEnabled true on Data Mappers. It governs the cold
path, and the cold path decides what every subsequent warm read returns.
Recommended Workflow
- Establish the runtime (standard vs managed package) and confirm Platform
Cache partition allocation is non-zero. Stop here if it is zero — nothing
downstream is measurable until it is fixed.
- Measure the read path cold, as a user from the target audience. Record p50
and p95 and the serialized payload size in bytes.
- Classify the payload: identical for everyone, or scoped to a person. This
choice — not the desired hit ratio — sets
responseCacheType to org or
session. Anything guest-reachable or containing PII defaults to no cache.
- Set a TTL inside the platform range (5 min – 48 h org, 5 min – 8 h session)
that matches the agreed freshness contract. If the contract is tighter than
5 minutes, record the decision not to cache and stop.
- Design invalidation before shipping: a version discriminator inside the
cache key for routine releases, plus a documented purge path for incidents.
A TTL alone is a staleness bound, not an invalidation mechanism.
- Verify in the runtime context, as two different users, comparing payloads
and not only elapsed time. Designer preview timings do not demonstrate the
response cache.
- Instrument hit ratio and cold-start load. Plan capacity for the cold-start
spike that follows an eviction — cache "isn't persisted" and an Apex deploy
may clear it.
Review Checklist
Worked Examples (see references/examples.md)
- Naming the layer — the three caches, and which one your symptom belongs to
- Reference-data Data Mapper — the full Options-tab and metadata configuration
- The cache that silently did nothing — partition allocation
- Cache key characters — the
Cache.InvalidParamException reproduction
- Org vs session from the payload — deciding on audience, not latency
- Invalidation on deploy — the case nobody configures
Common Gotchas (see references/gotchas.md)
- TTLs below 5 minutes are below the platform floor and do not mean what they say
- Keys with
: or = throw Cache.InvalidParamException
- Cached data is unencrypted and warm reads do not re-check sharing
isMetadataCacheDisabled is a negative that defaults to false
- The IP metadata type documents a cache type but no TTL field — which means
the duration does not round-trip through metadata, not that the setting
is missing from the designer
- Standard runtime and managed package have parallel, differently-behaving docs
Top LLM Anti-Patterns (full list in references/llm-anti-patterns.md)
- Redis-style punctuated cache keys
- TTL values below the 5-minute floor
- Inventing property names (
cacheEnabled, isCacheable, cacheTTL)
- Answering with managed-package behaviour for a standard-runtime org
- Org cache for anything the caller can key
- Treating TTL as the invalidation design
Related
- omnistudio/integration-procedure-cacheable-patterns — owns cache-key
design, partition selection, the Cache Block element, and invalidation for
Integration Procedures specifically.
- omnistudio/omniscript-session-state — when the requirement is durability
across a logout rather than latency, session cache is the wrong store.
- omnistudio/omnistudio-security — Required Permission, guest exposure, and
the security settings referenced in
gotchas.md §4.
- standards/decision-trees/performance-tuning.md — read before concluding
that caching is the right lever. A cache layered over an unselective query
hides the defect rather than fixing it.
Official Sources Used
See references/well-architected.md for the full source list with the
specific claim each source grounds.
1---2name: omnistudio-cache-strategies3description: Configure caching on DataRaptors and Integration Procedures for response-time gains. Triggers: OmniStudio cache, DataRaptor cache, IP cache TTL. NOT for IP-specific cacheable design — use omnistudio/integration-procedure-cacheable-patterns.4---56# OmniStudio Cache Strategies78Use this skill when deciding whether, where, and how to cache an OmniStudio9read path — and when diagnosing a cache that appears configured but is not10changing anything. It covers the three distinct caches that share the word11"cache" in OmniStudio, the Platform Cache limits every one of them inherits,12and the security consequences of serving a payload that was computed for13somebody else.1415---1617## Before Starting1819- **Which runtime is this org on?** Standard runtime and the Vlocity managed20 package have separate documentation, separate settings, and in places21 separate behaviour. `OmniStudioSettings.enableStandardOmniStudioRuntime`22 (API 65.0+) and `enableOaForCore` (64.0+) answer the question. Most23 published OmniStudio writing describes the package; assume nothing until24 you have checked.25- **Is Platform Cache actually allocated?** A partition with no capacity26 produces no error and no speedup. Verify allocation in Setup before27 scheduling any tuning work.28- **What is the freshness contract in business terms?** Not "as fresh as29 possible" — a number, agreed with whoever owns the data. The platform's30 5-minute TTL floor means some answers rule caching out entirely.31- **Who can reach this component?** Internal only, authenticated portal, or32 guest. The answer changes the cache type and may forbid caching outright.3334---3536## The Three Caches3738Naming the layer is the whole diagnostic. These are independent:3940| Layer | Stores | Configured by | Symptom when misconfigured |41|---|---|---|---|42| **Component metadata cache** | the compiled component definition | `isMetadataCacheDisabled` (boolean, default `false` — so it is **on** by default) on `OmniIntegrationProcedure` and `OmniScript` | slow cold start after deploy |43| **Response cache** | the output payload | Data Mapper Options tab (**Platform Cache Type**, **Time to Live in Minutes**); IP **Cache Configuration** section (whole response) or **Cache Block** element (enclosed steps); `responseCacheType` in metadata, plus `responseCacheTtlMinutes` on the Data Mapper type only | warm reads no faster than cold |44| **Platform Cache** | the underlying key/value substrate | Setup → Platform Cache partition allocation | nothing is cached at all, silently |4546`isMetadataCacheDisabled` is a negative. Default `false` means metadata47caching is already enabled; setting it `true` turns caching **off**. It is a48debugging lever, not a performance lever, and flipping it will not change what49a warm read returns.5051---5253## The Limits That Decide The Design5455Every OmniStudio response cache sits on Platform Cache and inherits its56bounds. These are the numbers that most often invalidate a proposed design:5758| Constraint | Value |59|---|---|60| TTL minimum (org and session) | 300 s / 5 minutes |61| TTL maximum — org cache | 172,800 s / 48 hours (default 86,400 s / 24 h) |62| TTL maximum — session cache | 28,800 s / 8 hours |63| Maximum cache key size | 50 characters |64| Cache key characters | **alphanumeric only** — `put()` throws `Cache.InvalidParamException` otherwise |65| Maximum size of a single cached item | 100 KB |66| Minimum partition size | 1 MB |67| Maximum local cache per partition, per request | 500 KB session / 1,000 KB org |6869Three consequences worth internalising:70711. A freshness requirement tighter than 5 minutes is a decision **not to72 cache**, not a smaller number in the TTL field.732. The Redis-style key `catalog:v2:region=NA` is illegal on this platform.74 Use camelCase with no separators.753. Caching the whole aggregate response usually exceeds 100 KB. Cache the76 resolved decision instead.7778---7980## Security Consequences Of A Warm Read8182A cache hit returns a payload computed during somebody else's request, under83that request's permission evaluation. Two documented facts and one reported84behaviour follow:8586- **Documented.** **"Data in the cache isn't encrypted."** Shield Platform87 Encryption does not follow a value into a cache entry.88- **Documented.** Org cache is addressed by a key. If the key is derived from89 **caller-supplied** inputs rather than a **server-resolved** subject, the90 caller chooses which entry to read. On a guest-reachable page this is a91 cross-tenant read.92- **Reported, not documented.** Metadata caching is reported to let a component93 execute for a user who would fail its **Required Permission** check on a cold94 run, because that check sits on the path the cache skips. Treat this as a95 reason not to lean on Required Permission as your only authorization96 boundary — not as a Salesforce-documented behaviour you can cite. See97 `gotchas.md` §4 for the provenance.9899<!-- UNVERIFIED: the Required Permission bypass in the third bullet is not100stated in any Salesforce-published doc I could read. It traces to AppOmni's1012025 Salesforce Industry Cloud security research, reported via CSO Online and102Information Security Buzz. The behaviour itself, its scope (standard runtime vs103managed package), and the remediation settings are all unconfirmed against104Salesforce. Do not present it to a customer as documented platform behaviour;105reproduce it in a sandbox first. -->106107The defensive posture the third bullet implies is sound regardless of whether108the specific bypass reproduces in your org: an access check that runs only on a109cold path is not an authorization boundary. Gate on the object and field110permissions of the running user and on the sharing model, which are evaluated111per call.112113Keep `fieldLevelSecurityEnabled` true on Data Mappers. It governs the cold114path, and the cold path decides what every subsequent warm read returns.115116---117118## Recommended Workflow1191201. Establish the runtime (standard vs managed package) and confirm Platform121 Cache partition allocation is non-zero. Stop here if it is zero — nothing122 downstream is measurable until it is fixed.1232. Measure the read path cold, as a user from the target audience. Record p50124 and p95 and the serialized payload size in bytes.1253. Classify the payload: identical for everyone, or scoped to a person. This126 choice — not the desired hit ratio — sets `responseCacheType` to `org` or127 `session`. Anything guest-reachable or containing PII defaults to no cache.1284. Set a TTL inside the platform range (5 min – 48 h org, 5 min – 8 h session)129 that matches the agreed freshness contract. If the contract is tighter than130 5 minutes, record the decision not to cache and stop.1315. Design invalidation before shipping: a version discriminator inside the132 cache key for routine releases, plus a documented purge path for incidents.133 A TTL alone is a staleness bound, not an invalidation mechanism.1346. Verify in the runtime context, as two different users, comparing payloads135 and not only elapsed time. Designer preview timings do not demonstrate the136 response cache.1377. Instrument hit ratio and cold-start load. Plan capacity for the cold-start138 spike that follows an eviction — cache "isn't persisted" and an Apex deploy139 may clear it.140141---142143## Review Checklist144145- [ ] Runtime recorded (standard vs managed package) before any doc was cited146- [ ] Partition allocation verified non-zero in Setup147- [ ] TTL within 5 min – 48 h (org) or 5 min – 8 h (session)148- [ ] `responseCacheType` matches the payload's audience, not its latency149- [ ] No org cache on a guest-reachable, portal, or PII component150- [ ] Cache keys are alphanumeric only and ≤ 50 characters, enforced in one helper151- [ ] Serialized payload measured against the 100 KB per-item ceiling152- [ ] Version discriminator in the key, plus a documented purge path153- [ ] `fieldLevelSecurityEnabled` true on cached Data Mappers154- [ ] No cache on a Data Mapper whose `type` is `Load`155- [ ] Read path treats a miss as a latency event, never an error156157---158159## Worked Examples (see `references/examples.md`)160161- *Naming the layer* — the three caches, and which one your symptom belongs to162- *Reference-data Data Mapper* — the full Options-tab and metadata configuration163- *The cache that silently did nothing* — partition allocation164- *Cache key characters* — the `Cache.InvalidParamException` reproduction165- *Org vs session from the payload* — deciding on audience, not latency166- *Invalidation on deploy* — the case nobody configures167168## Common Gotchas (see `references/gotchas.md`)169170- TTLs below 5 minutes are below the platform floor and do not mean what they say171- Keys with `:` or `=` throw `Cache.InvalidParamException`172- Cached data is unencrypted and warm reads do not re-check sharing173- `isMetadataCacheDisabled` is a negative that defaults to `false`174- The IP metadata type documents a cache *type* but no TTL field — which means175 the duration does not round-trip through metadata, not that the setting176 is missing from the designer177- Standard runtime and managed package have parallel, differently-behaving docs178179## Top LLM Anti-Patterns (full list in `references/llm-anti-patterns.md`)180181- Redis-style punctuated cache keys182- TTL values below the 5-minute floor183- Inventing property names (`cacheEnabled`, `isCacheable`, `cacheTTL`)184- Answering with managed-package behaviour for a standard-runtime org185- Org cache for anything the caller can key186- Treating TTL as the invalidation design187188---189190## Related191192- **omnistudio/integration-procedure-cacheable-patterns** — owns cache-key193 design, partition selection, the Cache Block element, and invalidation for194 Integration Procedures specifically.195- **omnistudio/omniscript-session-state** — when the requirement is durability196 across a logout rather than latency, session cache is the wrong store.197- **omnistudio/omnistudio-security** — Required Permission, guest exposure, and198 the security settings referenced in `gotchas.md` §4.199- **standards/decision-trees/performance-tuning.md** — read before concluding200 that caching is the right lever. A cache layered over an unselective query201 hides the defect rather than fixing it.202203## Official Sources Used204205See `references/well-architected.md` for the full source list with the206specific claim each source grounds.