---
updatedAt: 2026-02-25T12:53:43.000Z
---

# Cache fallback

Learn how to use the optional cache fallback feature of Commands.

# Client-side caching & cache fallback

## When to use it?

Every time an agent switches between multiple KViews, the KView gets reloaded. If the KView fetches data via Commands, an app can use up an org's or agent's API request limit rather quickly in some cases.

The optional caching feature of Commands makes KViews more **resilient to external APIs' request limits** in two ways (client-side caching and cache fallback):

1. It caches Command run responses for an org for a number of seconds defined by the app developer.
2. When the Command run response's error status is in the 4xx - 5xx range, it falls back to the latest cached response, dating back up to 24 hours.

[block:callout]
{
  "type": "info",
  "title": "24-hour fallback cache",
  "body": "Even though your Commands only cache run responses for 15 - 600 seconds, the responses are actually stored for 24 hours to allow falling back to a cached response when the external API returns an 4xx or 5xx error."
}
[/block]

## How to use it?

### Creating a command with caching enabled

Define a `cacheSeconds` field with a number value between `15` and `600` on a Command object in your app definition.

[block:code]
{
  "codes": [
    {
      "code": "{\n  \"app\": \"ecommstore\",\n  // ...\n  \"commands\": [{\n    \"name\": \"ecommstore.app.store.refundOrder\",\n    \"cacheSeconds\": 15\n    // ...\n  }]\n}",
      "language": "json"
    }
  ]
}
[/block]

### Using cached data

Whenever *Cache Fallback mode* is activated and you receive a cached response, the Command run response contains a `"cacheFallback": true`  flag.

The returned `statusCode` will be the cached response's status code, as will be the `responseHeaders`  and `responseBody`.

[block:code]
{
  "codes": [
    {
      "code": "{\n  \"data\": {\n    \"type\": \"command_run_response\",\n    \"attributes\": {\n      \"commandId\": \"60590ca2a1101b0013e8be7e\",\n      \"statusCode\": 200,\n      \"args\": {},\n      \"url\": \"https://api.example.com/v1/foo\",\n      \"requestHeaders\": {},\n      \"responseHeaders\": {\n       // ...\n      },\n      \"responseBody\": {\n        // ...\n      },\n      \"cacheFallback\": true\n    },\n    \"relationships\": {\n      // ...\n    }\n  }\n}",
      "language": "json"
    }
  ]
}
[/block]

## Org logging

Orgs are notified whenever *Cache Fallback mode* gets activated or deactivated via info-level Org Logs that list both the Command's name and the external API's returned error status code that caused the activation (or deactivation).

## How it works

* We only cache if a command's `cacheSeconds` field is defined.
* When *Cache Fallback mode* is deactivated and we find a cached response, we still fetch live data if the cached value is older than `cacheSeconds`.
* When the API returns an error response status (4xx - 5xx), *Cache Fallback mode* gets activated for the respective combination of org, command and request params (e.g. headers and body).
* When *Cache Fallback mode* is activated:
  * We return cached values even if they are older than `cacheSeconds`.
  * We try to fetch live data from API every on every 5th command run and if we receive live data again (2xx - 3xx status), *Cache Fallback mode* gets deactivated.