Response Caching
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=Falseor--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]:1000Cacheable 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]:1000The 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:1000The 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
GETover HTTPS - The response status is
200 - The URL path ends in one of your selected extensions
- The response has no
Set-Cookieheader - The response permits caching, or
_cacheignoreheader-1is 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.jsandservice-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/simport 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.
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