# Speed up a website with the cache

> Turn a website's cache on or off, choose how long Coritan's network keeps copies, let signed-in visitors skip it and clear it after you publish.

Source: https://www.coritan.com/docs/websites/caching/

In the dashboard:

- /dashboard/websites/…/caching: https://www.coritan.com/dashboard/websites

Coritan's network can keep copies of the files on your website that look the same to every visitor, such as pictures and fonts. A visitor who asks for one gets the copy from Coritan's network without a trip to your origin, so the page loads faster and your origin has less to send. A website's **Caching** tab shows what the cache keeps, and lets you turn it off, choose how long it keeps copies, let signed-in visitors skip it and clear it after you change a file.

## Before you begin

- The hostname is on Coritan's network: a DNS record with **Proxied** on ([Proxied records](/docs/websites/dns/#proxied-records)), or a web proxy ([Manage a website's origin](/docs/websites/proxy/)). Until the domain has one, the tab offers **Proxy a DNS record** and **Set up a web proxy** in place of its settings.
- Once [account plans open on your account](/docs/billing/account-plans/#plans-open-in-stages), changing the cache and clearing it come with the Pro, Business and Enterprise plans ([How account plans work](/docs/billing/account-plans/#what-each-plan-includes)). On the Free plan the tab shows the settings without letting you change them, with `Cache settings come with the Pro plan`. The cache keeps working as its settings say.

## What Coritan's network keeps {#what-is-kept}

The cache keeps:

- Pictures, fonts, sound and video files. Coritan's network goes by the `Content-Type` your origin sends (`image/`, `font/`, `audio/` or `video/`). An answer with no type, or with `application/octet-stream`, counts when its path ends in an extension such as `.png`, `.jpg`, `.svg`, `.woff2`, `.mp3` or `.mp4`.
- Scripts, stylesheets and JSON files under `/assets/v/` or `/_next/static/` that your origin marks `immutable` in its `Cache-Control` header. Their address changes whenever they do, as a Next.js build names its files.
- Answers under `/api/v1/orgs/` that your origin marks `public` with an `s-maxage` time, for 15 seconds at most, whatever **Keep copies for** says. A request there that sends an API key, or a cookie other than the one that remembers the answer to our math question, always reaches your origin.

The cache never keeps:

- Pages, and any other file not listed above.
- An answer that sets a cookie, or whose `Cache-Control` header says `private` or `no-store`.
- An answer whose `Vary` header names a request header other than `Accept-Encoding`.
- A request with an `Authorization` header, or with the cookie you set under **Cookie name** ([Let signed-in visitors skip the cache](#skip-the-cache)).
- Any request but `GET` and `HEAD`, and any answer but `200`.
- A file over 10 MB, or one your origin sends without a `Content-Length`.
- Anything under `/api/`, `/ws/`, `/admin`, `/docs`, `/openapi` or `/health`, apart from `/api/v1/orgs/` as above and files under `/docs/assets/`.

A copy stays for the time in your origin's `Cache-Control` header: `s-maxage`, else `max-age`, or 1 hour when it gives neither. A time of `0` keeps nothing. Coritan's network can drop a copy sooner to make room for others.

A picture, font, sound or video file has one copy whatever its query string, so `/images/logo.png?v=2` gets the same copy as `/images/logo.png`.

An answer from a copy carries the response header `X-Cache: HIT`. An answer from your origin carries `X-Cache: MISS`, even for a page the cache never keeps. Neither header comes when the cache is off, on a request but `GET` and `HEAD`, on a request with an `Authorization` header, or under the paths in the last item above.

## Open the Caching tab

1. In the dashboard, go to [Websites](https://www.coritan.com/dashboard/websites) and open the domain.
2. Select the **Caching** tab.
3. If the domain has more than one hostname on Coritan's network, choose one under **Settings for**. Each hostname has a cache and settings of its own. The tab opens on the hostname you chose last, or on the domain itself.

## Turn the cache on or off

On the **Cache** card, turn **Cache on our network** on or off. The change saves at once and shows `Cache turned off for www.example.com.` or `Cache turned on for www.example.com.`. While the cache is off, every request goes to your origin.

## Choose how long copies are kept {#keep-copies-for}

On the **Cache** card, choose a time under **Keep copies for**: **As long as your origin says**, **5 minutes**, **1 hour**, **4 hours**, **1 day**, **1 week** or **30 days**. The change saves at once and shows `Cache time for www.example.com saved.`.

A time here replaces the one in your origin's `Cache-Control` header, for the files the cache keeps anyway. It does not make a page or any other file cacheable. An answer marked `private` or `no-store`, or with a time of `0`, is still not kept. **Keep copies for** waits while the cache is off.

## Let signed-in visitors skip the cache {#skip-the-cache}

The people who edit your site want to see a new picture as soon as they upload it. Name the cookie your site gives to signed-in visitors, and Coritan's network sends every request that carries it to your origin.

1. On the **Skip the cache for signed-in visitors** card, enter the cookie's name, or the start of it, under **Cookie name**. Any cookie whose name starts with that text counts, so `wordpress_logged_in` also matches `wordpress_logged_in_8f3a`.
2. Select **Save cookie**. The card shows `Saved wordpress_logged_in for www.example.com. Visitors with that cookie now skip the cache.`

For a WordPress site, select **Use the WordPress cookie**, which saves `wordpress_logged_in` at once. WordPress sets it for everyone who signs in, WooCommerce customers too, and for no one else.

A cookie name has 1 to 128 characters: letters, digits and the symbols `` !#$%&'*+-.^_`|~ ``, with no spaces. The card checks the name before it saves it. To let every visitor use the cache again, select **Clear**, or empty the field and select **Save cookie**.

> [!IMPORTANT]
> Choose a cookie that only signed-in visitors have. Every request that carries it goes to your origin, so a cookie that every visitor gets, such as a shopping cart's or one set on the first visit, sends all your traffic there.

## Clear the cache {#clear-the-cache}

Clear the cache after you change a file at the same address, so visitors get the new version at once. Each file then comes from your origin on its next request, and the cache keeps it again from there. You can clear the cache of each hostname 30 times in any hour. Clearing everything and clearing some files count the same, and a clear that Coritan refuses does not count.

### Clear some files

1. On the **Clear the cache** card, select **Clear some files…**.
2. Under **Addresses**, enter up to 30 addresses, one on each line. Each is a path, such as `/images/logo.png` or `/pricing?plan=pro`, or a full `http` or `https` address on the hostname, such as `https://www.example.com/css/site.css`.
3. Select **Clear files**.

The dialog checks the list before it sends it and names the line it cannot take: an address on another hostname, a line that is neither a path nor an address, or more than 30 lines. A path and a full address for the same file count once. When it worked, the dialog closes and shows `Cleared 3 files from the cache of www.example.com.`.

### Clear everything

1. On the **Clear the cache** card, select **Clear everything…**.
2. Select **Clear everything** to confirm.

Coritan's network drops every copy it holds of the hostname's files and shows `Cleared every file from the cache of www.example.com.`. Pages load those files from your origin until the copies build up again.

### Development mode does not skip the cache

On some other networks, a development mode turns the cache off while you work on a site. On Coritan, [development mode](/docs/platform/glossary/#development-mode) shows your origin's address and the exact connection failure on Coritan's error pages. Visitors still get files from the cache, so clear the files you changed to see them at once.

## Result

The switch and the time save as soon as you change them, and the cookie saves when you select **Save cookie**. Each change shows a confirmation that names the hostname. To check one file, open your browser's developer tools and read the file's response headers: `X-Cache: HIT` means it came from a copy.

## Troubleshooting

A visitor still sees the old version of a file
: The cache serves its copy until its time runs out: the one under **Keep copies for**, or your origin's. Clear the file with **Clear some files…**. A new query string such as `?v=2` on a picture, font, sound or video file does not get it a new copy, so clear it or give it a new file name. Browsers keep their own copies too, for the time your origin gives, so reload with <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>R</kbd>, or <kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>R</kbd> on a Mac.

A file always answers with `X-Cache: MISS`
: Compare its response headers with [What Coritan's network keeps](#what-is-kept). The usual causes are a `Set-Cookie` header, `private`, `no-store` or a time of `0` in `Cache-Control`, a `Vary` header other than `Accept-Encoding`, a size over 10 MB or no `Content-Length`. A page is never kept. A visitor who has the cookie under **Cookie name** always gets `MISS`.

A file answers with no `X-Cache` header
: The cache is off for the hostname, the request is not a `GET` or `HEAD`, it carries an `Authorization` header, or its path is under one of those in the last item of [What Coritan's network keeps](#what-is-kept).

`You cleared the cache of www.example.com 30 times in the last hour, which is the limit.`
: Each clear stops counting an hour after you made it, so try again later. The API answers `429` with `Retry-After: 3600`.

`play.example.com is another website. Each address must be on www.example.com.`
: Each address must be on the hostname chosen under **Settings for**. Choose the other hostname, then clear its files there.

`images/logo.png is not a path or a web address. Start it with / or https://.`
: Start each line with `/`, or with `http://` or `https://` and the hostname.

`Cache settings come with the Pro plan`
: Your account is on the Free plan, so the tab shows the settings without letting you change them. Choose a plan that includes them ([Choose or change your account plan](/docs/billing/change-account-plan/)). The API answers `402` with `entitlement_exceeded`.

## Related

- [How web proxies work](/docs/proxies/web-proxies/)
- [Protect a website](/docs/websites/waf/)
- [View web proxy traffic](/docs/websites/traffic/)

## With the API

The cache settings are fields of the hostname's web proxy, and each hostname is one route. `GET /api/v1/proxy/routes` lists your routes with their `id` and `domain`. Change the settings with `PATCH /api/v1/proxy/routes/{route_id}`:

```bash
curl -X PATCH https://api.coritan.com/api/v1/proxy/routes/31 \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cache_enabled": true, "cache_max_age": 86400, "cache_bypass_cookie": "wordpress_logged_in"}'
```

```json
{"message": "Route updated"}
```

`cache_enabled`
: `true` keeps copies, `false` sends every request to your origin.

`cache_max_age`
: Seconds, from `0` to `31536000`. `0` or `null` follows your origin's `Cache-Control` header.

`cache_bypass_cookie`
: A cookie name, or the start of one, of 1 to 128 characters. `null` or `""` removes it.

A value that is not a cookie name answers `422` with `` "wp logged in" is not a cookie name. Use letters, digits and the symbols !#$%&'*+-.^_`|~, with no spaces. ``, and one longer than 128 characters with `A cookie name can be up to 128 characters.`.

Clear every file of the hostname with no body:

```bash
curl -X POST https://api.coritan.com/api/v1/proxy/routes/31/cache/purge \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{"success": true, "domain": "www.example.com", "cleared": "everything"}
```

Clear some files with `urls`, 1 to 30 paths or full addresses on the hostname:

```bash
curl -X POST https://api.coritan.com/api/v1/proxy/routes/31/cache/purge \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["/images/logo.png", "https://www.example.com/images/logo.png", "/css/site.css?v=2"]}'
```

```json
{"success": true, "domain": "www.example.com", "cleared": "urls", "urls": ["/images/logo.png", "/css/site.css?v=2"]}
```

`urls` in the answer lists each file once, as a path. An address on another hostname answers `422` with `play.example.com is another website. Each address must be on www.example.com.`, and more than 30 addresses answer `422` too.

The 31st clear of a hostname in an hour answers `429` with a `Retry-After` header in seconds:

```json
{
  "detail": {
    "error": "rate_limited",
    "message": "Too many requests for this action. Try again later.",
    "action": "proxy.cache_purge",
    "retry_after_seconds": 3600
  }
}
```

Once account plans open on your account, a plan without cache settings answers `402` with `entitlement_exceeded` to a clear, and to a `PATCH` only when `cache_enabled`, `cache_max_age` or `cache_bypass_cookie` would change:

```json
{
  "detail": {
    "code": "entitlement_exceeded",
    "entitlement": "cache_controls",
    "limit": false,
    "used": 0,
    "upgrade": {"plan": "plan-pro", "addon": null},
    "message": "Your Free plan does not include cache settings. To use it, upgrade to Pro."
  }
}
```

A refusal for the plan or for an address does not count towards the 30 clears.

## API

- `POST /api/v1/proxy/routes/{route_id}/cache/purge`: Drop copies of this website's files on every edge node (https://www.coritan.com/docs/api/reference/client/reverse-proxy/#op-post-api-v1-proxy-routes-route-id-cache-purge)
