Offline behaviour and caching
The SDK decides campaigns on the device, so most of it keeps working without a connection. This page explains which configuration the SDK applies at launch and offline, how often it refreshes, what happens to events, grants and activation answers while the device is offline, and what a long time offline means for your campaigns. Read it before you decide what to put in the configuration you bundle with your app.
Configuration at launch
Section titled “Configuration at launch”At launch the SDK looks at two local copies of the signed configuration and applies the best valid one:
- The bundled configuration. A signed configuration file you ship inside your app. It is what a fresh install runs before it has ever reached the network.
- The cached configuration. The last configuration the SDK downloaded and accepted, stored with its ETag.
Both copies are verified exactly like a download: signature, workspace, version, expiry and minimum SDK version. A copy that fails is ignored. Between valid copies, the higher version wins, and at equal version a downloaded copy outranks the bundled one. If neither is valid, nothing renders until a valid download arrives. See Signed configuration.
If your app sets no configuration URL, the SDK runs on the bundled copy alone.
Refresh
Section titled “Refresh”The SDK downloads the configuration at cold start and then again while the app is in the foreground.
- Interval. The configuration’s
ttl_secondssets how often the SDK refreshes. The SDK clamps it to 300 to 86,400 seconds (5 minutes to 24 hours). A negative value rejects the configuration. - Floor. The SDK never downloads more often than every 300 seconds. An explicit refresh from your app still respects that floor.
- Conditional requests. Each download sends the cached ETag, so an unchanged configuration costs a
304 Not Modifiedwith no body. - Failures. On a network error, a 429 or a 5xx response, the SDK backs off with jitter and honours
Retry-After, but never waits more than 1 hour before trying again. Download timeouts are 30 seconds overall. - Background. A backgrounded app downloads nothing. It catches up on its next foreground, once a refresh is due.
On any failure or rejection the SDK keeps the configuration it already has.
What renders offline
Section titled “What renders offline”| Offline behaviour | |
|---|---|
| SDK-rendered components and host-rendered decisions | Decided on the device from the current configuration, as usual |
Kills with enabled: false |
Applied once a configuration carrying them is downloaded. A device that stays offline keeps the last configuration it accepted |
| Configuration expiry | Applied with no download needed. Past expires_at, every campaign is inactive |
| Activation answers | Trusted for at most 10 minutes, and unknown at once when a poll fails, for example offline. Unknown does not switch campaigns off |
| Offers | Shown only while a grant fetched earlier is still valid; otherwise the placement falls through to the next campaign |
| Images from remote hosts | Not shown if they cannot be downloaded; the component still renders. Bundled asset://img/ images load from your app |
Expiry and long periods offline
Section titled “Expiry and long periods offline”Every configuration has an expiry, at most 400 days after it was issued. Past it, every campaign is inactive, whether or not the device is online. A 304 Not Modified does not extend the expiry, so Grona re-signs and serves a new version before the current one expires. A device that stays offline past the expiry of its best local copy shows nothing until it downloads a newer one.
Activation answers
Section titled “Activation answers”If your app uses an activation source to switch campaigns off from an external system, the SDK polls it every 5 minutes in the foreground and waits at most 10 seconds for each answer. An answer counts for at most 10 minutes. After that, or as soon as a poll fails or times out (for example offline), activation is unknown. Activation can only narrow, so unknown leaves each campaign as the configuration says. See Campaign activation and kill switch.
Grants
Section titled “Grants”Grants are fetched through your app’s grant source when a shopper is identified, again shortly before the nearest grant expires, and at least once an hour, with a 10-second timeout. A failed fetch is retried with backoff of up to 15 minutes. Grants live in memory only and last at most 24 hours each.
- Offline after sign-in, no fetch completes, so offers log
delivery: grants_pendingand are not shown. - A grant fetched earlier stays usable until it expires, so an offer already granted can still render offline.
- After the app restarts, the SDK has no grants until a new fetch completes.
Your order backend verifies any grant at order time, so an offline device can never apply a treatment on its own. See Offers and grants.
The event queue
Section titled “The event queue”- Before consent, events are kept in memory only (at most 500) and never written to disk.
- After consent is granted and with an events endpoint configured, events are written to an on-disk queue, so they survive restarts and periods offline.
- Limits. The on-disk queue holds at most 1,000 events or 7 days, oldest dropped first. The limit is applied at every start.
- Offline, sends fail and the events stay in the queue, within those limits, for a later send. The SDK retries each send at most 3 times with backoff, then waits for the next scheduled flush.
See Events and exposure and Consent and data minimisation.