# Configure the cache

> Set the caching level, browser cache TTL, development mode, cache deception armor, stale content and maximum object size.

All cache settings live under `cache` in the zone's edge settings. Each one can be set for the whole zone or for one name: in the dashboard with **Scope**, in the CLI with `--host`, in the API under `hosts.<name>.cache` and in MCP with `host`. A name inherits every setting it doesn't set itself. See [Per-name settings](https://developers.openwaf.dev/rules/per-name-settings/).

In the dashboard, everything on this page is in **Caching**; save with **Save changes** and a reason.

## Turn the cache on or off

`cache.enabled` (**Cache at the edge**), off by default. Turning it off makes every request `DYNAMIC` from the next configuration on.

## Caching level

`cache.query.mode`, `cache.query.params` and `cache.query.sort` decide how the query string enters the cache key: the whole query (default), none, only some parameters or all but some. See [Cache keys](https://developers.openwaf.dev/cache/cache-keys/#query-string).

```sh
openwaf-cloud ctl zones set example.com cache.query.mode=exclude 'cache.query.params:=["utm_*","fbclid","gclid"]' --reason "ignore ad parameters"
```

## Browser cache TTL

`cache.browser_ttl`, in seconds. `0` (**Respect existing headers**, the default) forwards your origin's `Cache-Control` unchanged. A value greater than `0` **raises** the `max-age` sent to browsers to at least that value; a larger `max-age` from the origin still wins, and responses browsers must not cache (`no-store`, `private`…) are left alone. The dashboard offers durations from 30 minutes to 1 year.

## Development mode

`cache.dev_mode_until` is a time (RFC 3339) until which the cache is bypassed: every request goes to your origin and is marked `DYNAMIC`, so you see changes immediately. Nothing is deleted; purge if visitors must see the change too.

**Dashboard**

Turn on **Development mode** and save: it switches itself off after 3 hours.

**CLI**

```sh
openwaf-cloud ctl zones set example.com cache.dev_mode_until=2026-10-27T18:00:00Z --reason "redesign"
openwaf-cloud ctl zones set example.com cache.dev_mode_until:=null --reason "done"
```

**API**

```json
{"cache": {"dev_mode_until": "2026-10-27T18:00:00Z"}}
```

`{"cache": {"dev_mode_until": null}}` turns it off.

**MCP**

`update_settings` with `{"settings": {"cache": {"dev_mode_until": "2026-10-27T18:00:00Z"}}}`, or `null` to turn it off.


A name can switch off a development mode that is on for the whole zone by setting its own value in the past (in the dashboard, turn it off within the name's scope).

## Cache deception armor

`cache.deception_armor`, on by default. Doesn't store a response whose content type contradicts the URL extension, such as an HTML page at `/profile/x.css`. See [Default behavior](https://developers.openwaf.dev/cache/default-behavior/#deception-armor).

> **Danger**
>
> With the armor off, a personal page requested as `/account.php/x.css` could be stored and served to other visitors. Keep it on unless you are sure every static URL of the site returns its real file type.


## Stale content

| Setting | Dashboard | Default | Effect |
|---|---|---|---|
| `cache.serve_stale.while_revalidate` | Serve stale while revalidating | `true` | Honor the origin's `stale-while-revalidate`: serve the expired copy while it refreshes in the background. |
| `cache.serve_stale.on_error_max_s` | Serve stale when the origin fails | `86400` (24 h) | How long after expiry a copy may still be served when the origin is down or answers `500`/`502`/`503`/`504`, if the origin sent no `stale-if-error`. `0` = never; at most 30 days. |

## Maximum object size

`cache.max_object_mb`, from `1` to `512`, default `100`. Larger responses are passed through to the visitor without being stored.

```sh
openwaf-cloud ctl zones set example.com --host videos.example.com cache.max_object_mb=512 --reason "large videos"
```

## Go back to the defaults

In the API, `"cache": null` restores every cache setting of the zone to its default. For a name, `openwaf-cloud ctl zones set example.com --host www.example.com --unset cache --reason "inherit the zone"` makes it follow the zone again.

## Check the result

The effective configuration of a name shows the cache it really gets, after merging the zone's and the name's settings:

```sh
openwaf-cloud ctl zones effective example.com www.example.com
```

See [Effective configuration](https://developers.openwaf.dev/rules/effective-config/).
