The fail-safe resolution chain
Every present and prefetch resolves a placement through the same ordered chain. Each tier is tried until one yields a presentable flow:
If no tier yields a presentable flow, the resolve fails, and you handle it with the host fallback (
resolveSession returns null, or the presenter fallback renders).
Every analytics event carries the tier it was served from as delivery_source (network, cache, stale_cache, bundled_default), so offline and fallback renders are distinguishable in the dashboard. See Analytics.
The resolve deadline does not strand the cache
A live resolve that hitsresolveTimeout degrades the current caller to a fallback tier, but it does not cancel the in-flight request. The resolve keeps running to populate the cache, so the next caller hits a warm Tier 0. A slow network therefore never hangs onboarding, and the cost of a slow first present is not wasted. Concurrent resolves for the same key are also coalesced into one round-trip, so a prefetch and a present that race share a single request.
The no-fallback second chance
There is one case where the shortresolveTimeout buys nothing: a present-time resolve where Tier 0 and Tier 2 both miss and no bundled default (Tier 3) is registered. Failing fast there would just strand the user on a blank screen, so the SDK instead waits up to resolveNoFallbackTimeout (default 12 seconds, floored at resolveTimeout) for the real flow rather than giving up at 4s. The still-in-flight resolve usually lands within that window (for example a cold backend that answers in ~6s). When a stale or bundled tier is available, the short resolveTimeout still applies, so a slow network degrades instantly. Set resolveNoFallbackTimeout at or below resolveTimeout to disable this second chance. See Configuration.
Cache freshness (TTL)
A cached flow is “fresh” for a number of seconds, after which Tier 0 misses and the SDK re-resolves (falling back to the same entry as stale cache if the network fails). The TTL comes from the resolve response’scacheTtlSeconds; when the backend omits it, the SDK uses the environment default:
Because
development defaults to a 0 TTL, prefetching and “fast repeat present” have no visible effect there. Test caching behavior against staging or production. See Configuration.Identity-scoped cache keys
Cached flows are keyed by an identity fingerprint, a hash of the per-install user ID and any targeting attributes the resolve was personalized by. This guarantees a flow cached for one user (or one A/B variant) is never served to another after an identity change. The stale-cache tier keeps a fingerprint-agnostic last-known-good alias, so a previously-seen flow can still render offline even right after the identity changes.Enabling and disabling caching
Caching is on by default. Turn it off withcachingEnabled: false:
Clearing the cache
clearCache() is the lever to pull during testing when you have published a new flow version and want to bypass the TTL. It returns a promise (the disk delete is async), so await it before the next resolve, or a resolve fired immediately after can still read the old Tier-0 entry. In production, prefer attaching the new version in the dashboard and letting the TTL expire.
Common mistakes
- Testing caching against
development. The0default TTL means nothing stays fresh. Usestaging/production. - Disabling caching and expecting prefetch to work. Prefetch is a no-op with caching off.
- Expecting a republished flow to appear instantly. A fresh cached copy is served until its TTL expires, and the placement must point at the new version. Clear the cache or attach the new version. See Troubleshooting.
- Assuming offline always works. Offline rendering needs either a prior cache entry or a bundled default. Ship a bundled default for guaranteed offline onboarding.
Troubleshooting
- Old flow still showing after republish. The cache is fresh, or the placement still points at the old version. Attach the new version, then
clearCache()or wait out the TTL. - First present is slow on a poor network. Expected on a cold cache. Ship a bundled default and prefetch at launch so Tier 0/Tier 3 cover the first present. See Prefetching.
- A flow renders offline that you did not expect. It came from stale cache or a bundled default. Check the
delivery_sourcein debug logs.