# Response Caching

Source: https://docs.evomi.com/proxy-instructions/residential-proxies/expert-settings/caching/

**Note:** Expert settings are only available for **Core Residential Proxies**.

Static assets are the bulk of most page loads and rarely change between requests. Response caching lets Evomi store those assets — scripts, stylesheets, images, fonts — and serve them from our infrastructure on subsequent requests instead of fetching them through a residential IP again. Pages render faster and the target site sees far fewer requests from you.

Caching is opt-in per request. Append `_cache-` to your proxy password and choose which file types it should apply to.

**HTTPS needs one change on your side**

To store a response the proxy has to read it, so HTTPS on a cache-enabled password is re-signed with the Evomi Proxy CA rather than tunnelled untouched. Your client rejects that certificate by default, and requests fail during the TLS handshake until you do one of two things:

- **Skip certificate verification** — one flag in your client, such as `curl -k`, `verify=False` or `--ignore-certificate-errors`. This is what most users do.
- **Trust the Evomi CA** — a one-off install that keeps certificate verification switched on.

Either works. [Proxy Certificate](/proxy-instructions/integration-guides/proxy-certificate/) covers both, with copy-paste snippets per language.

## Implementation

Append `_cache-<types>` to your proxy password, where `<types>` is a comma-separated list of file extensions, one of the shorthand groups, or `all`:

<!--email_off-->
```bash
http://testuser:testpassword_cache-images@rp.evomi.com:1000
```
<!--email_on-->

### Cacheable Types

| Value | Expands to |
|-------------|-----------------------------------------|
| `images` | `png`, `jpg`, `jpeg`, `gif`, `svg`, `ico`, `webp` |
| `scripts` | `js`, `css`, `wasm`, `map` |
| `fonts` | `woff`, `woff2`, `ttf`, `eot`, `otf` |
| `all` | Every type listed above |

You can also name extensions individually and mix them with groups, so `_cache-images,js,woff2` and `_cache-png,jpg` are both valid. Only the extensions in the table are supported — `all` means all supported types, not every file on the page, so documents, media and API responses are never cached.

**An unsupported type disables caching silently**

If your list contains anything outside the table above, such as `_cache-html` or `_cache-mp4`, the whole list is rejected and the request continues as a normal uncached proxy request. It still succeeds, so a password that appears to do nothing is usually a typo in the type list. `_cache-` with no value behaves the same way.

## Cache Duration

Entries live for **120 minutes** by default. Override this with `_cacheduration-<minutes>`:

<!--email_off-->
```bash
http://testuser:testpassword_cache-all_cacheduration-30@rp.evomi.com:1000
```
<!--email_on-->

The origin still has a say. When the response carries a `Cache-Control: max-age`, the **shorter** of the two values wins, so a site that declares `max-age=60` caps the entry at one minute no matter how high you set `_cacheduration-`. A value below `1` or any non-numeric value is ignored and leaves the default in place.

More importantly, a response with **no** `Cache-Control` header at all is not cached. Many sites omit it on static assets, so a correct-looking `_cache-` password can still produce no cache hits.

### Ignoring the Origin's Headers

`_cacheignoreheader-1` caches responses regardless of what `Cache-Control` says, including assets with no header at all and assets marked `no-store`, `no-cache` or `private`. Your `_cacheduration-` value then applies verbatim:

<!--email_off-->
```bash
http://testuser:testpassword_cache-scripts_cacheduration-60_cacheignoreheader-1@rp.evomi.com:1000
```
<!--email_on-->

**The cache is shared, so only use this on public assets**

Cached entries are keyed by URL and shared across accounts, the same way a CDN works. That is safe for public static assets, which are byte-identical for everyone who requests them.

It is not safe for anything private. `_cacheignoreheader-1` overrides the `no-store`, `no-cache` and `private` directives that a site uses to mark a response as non-shareable, so using it on assets behind a login can place them in a cache other accounts read. Restrict it to public, unauthenticated assets, and leave it off when in doubt — responses that set a cookie are never cached under any setting, but that guard alone will not catch every private asset.

## What Gets Cached

A response is only stored when **all** of the following hold:

- The request is `GET` over HTTPS
- The response status is `200`
- The URL path ends in one of your selected extensions
- The response has no `Set-Cookie` header
- The response permits caching, or `_cacheignoreheader-1` is set

Never cached, regardless of configuration:

- Anything served over plain `http://`, or through the SOCKS5 endpoint — caching applies to HTTPS via the HTTP proxy endpoint only
- `sw.js` and `service-worker.js`, since a stale service worker would outlive the cache entry
- URLs with no file extension in the path, including most API endpoints
- Responses that set a cookie

Entries are matched on the full URL, including the query string, so versioned asset URLs such as `/app.js?v=1` and `/app.js?v=2` are stored separately and a new version is never served from an older entry. Matching is exact rather than normalised: if your client varies the order of query parameters between requests, each ordering is cached under its own entry.

## Bandwidth and Billing

A cache hit skips the residential IP entirely and is served straight from our infrastructure, which is where the speed benefit comes from. It is still **billed as normal traffic** at your usual rate: caching reduces latency and the load you place on the target site, not the bandwidth deducted from your plan.

`_cache-` itself carries no bandwidth multiplier. Any multiplier you see comes from the geo or expert filters you pair it with, at their usual rates.

## Examples

#### CURL

  ```bash
# Cache images and fonts, skipping certificate verification
curl -k -x http://rp.evomi.com:1000 -U testuser:testpassword_cache-images,fonts https://ip.evomi.com/s

# Cache everything supported for 30 minutes, trusting the CA instead
curl --cacert evomi.crt -x http://rp.evomi.com:1000 -U testuser:testpassword_cache-all_cacheduration-30 https://ip.evomi.com/s
```

#### Python

  ```Python
import requests

proxy_pass = "testpassword_cache-scripts,images"
proxy_url = f"http://testuser:{proxy_pass}@rp.evomi.com:1000"

proxies = {
  "https": proxy_url,
}
# Or verify="evomi.crt" if you installed the CA
response = requests.get("https://ip.evomi.com/s", proxies=proxies, verify=False)
print(response.text)
```

#### JavaScript

```JavaScript
const puppeteer = require('puppeteer');

// Caching pairs well with browser automation, where one page load
// pulls dozens of static assets through the proxy.
const browser = await puppeteer.launch({
  args: [
    '--proxy-server=http://rp.evomi.com:1000',
    '--ignore-certificate-errors',
  ],
});
const page = await browser.newPage();
await page.authenticate({
  username: 'testuser',
  password: 'testpassword_cache-all',
});
await page.goto('https://ip.evomi.com/s');
```

## Common Use Cases

- Browser automation and scraping, where every page load re-fetches the same assets
- Crawling many pages on one site that share a stylesheet, script bundle and icon set
- Reducing your request footprint on targets that rate-limit aggressively
- Speeding up repeated page loads during test and development runs

## Troubleshooting

| Symptom | Likely cause |
|-------------------------------------------|--------------------------------------------------------------|
| TLS or certificate errors on every request | Your client is still verifying the re-signed certificate — skip verification or trust the CA, see [Proxy Certificate](/proxy-instructions/integration-guides/proxy-certificate/) |
| Requests succeed but nothing seems cached | An unsupported extension in the list, or the origin sends no `Cache-Control` — try `_cacheignoreheader-1` on public assets |
| Cached response served after the site updated | The entry is still within its duration; there is no manual purge, so shorten `_cacheduration-` for assets that change often |

Responses carry no hit-or-miss header today, so the practical way to confirm caching is working is to request the same asset twice and compare response times.

**Pro Tip**  
Start narrow and widen once you have confirmed hits. Fonts and images are the safest and highest-volume wins, while scripts change most often:  
`_cache-fonts`  
`_cache-images,fonts`  
`_cache-all_cacheduration-30`
