Response 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 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:

http://testuser:[email protected]:1000

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>:

http://testuser:[email protected]:1000

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:

http://testuser:testpassword_cache-scripts_cacheduration-60_cacheignoreheader-1@rp.evomi.com:1000
⚠️

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:

# Cache images and fonts, skipping certificate verification
curl -k -x http://testuser:testpassword_cache-images,[email protected]:1000 https://ip.evomi.com/s

# Cache everything supported for 30 minutes, trusting the CA instead
curl --cacert evomi.crt -x http://testuser:[email protected]:1000 https://ip.evomi.com/s
import requests

proxies = {
"https": "http://testuser:testpassword_cache-scripts,[email protected]:1000",
}
# Or verify="evomi.crt" if you installed the CA
response = requests.get("https://ip.evomi.com/s", proxies=proxies, verify=False)
print(response.text)
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
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