Caching and compression: the free speed nobody claims
Cache-Control that actually caches, why a hashed filename changes everything, and the compression setting still missing on half the sites we scan.
Infrastructure · Published: 30 August 2026 · 3 min read · Анна Ковалёва
Most performance work is expensive: rewriting components, deferring scripts, arguing about a framework. Two settings are not. They live in a config file, they take an afternoon, and they are still wrong on a large share of production sites.
Compression first
Text compresses by seventy to eighty percent. HTML, CSS, JavaScript, JSON, SVG — all text. If the response has no Content-Encoding, you are shipping four times the bytes for nothing.
Brotli beats gzip by roughly fifteen percent on the same content and is supported everywhere that matters; keep gzip as the fallback. Two mistakes are common: compressing images (JPEG and PNG are already compressed — you spend CPU to save nothing) and forgetting that the setting applies per MIME type, so a subdomain serving JSON from a different config quietly ships it raw.
Cache-Control, honestly
The header answers two questions: may this be stored, and for how long. The useful patterns are few.
Hashed assets — /app.4f2a91.js:
Cache-Control: public, max-age=31536000, immutable
A year, and never revalidated. Safe precisely because the filename changes when the content does. This is the single biggest win available, and it only works if your build actually hashes filenames.
HTML:
Cache-Control: no-cache
Counter-intuitively this does not mean "do not cache". It means "store it, but revalidate before use". The browser sends an If-None-Match and usually gets a 304 with no body — fast, and never stale.
Personalised responses:
Cache-Control: private, no-store
For anything a shared cache must never keep: account pages, carts, anything behind a login.
The mistakes that cost the most
Short max-age on hashed files. max-age=600 on a filename that includes a content hash throws away the entire benefit.
Long max-age on unhashed files. /logo.png cached for a year means the redesign does not reach anyone who visited before it.
Missing ETag or Last-Modified on HTML. Without a validator the browser cannot ask "has this changed"; it re-downloads the whole document.
Vary set wrong. Vary: User-Agent fragments a CDN cache into thousands of near-identical entries and is almost never what you meant.
Prove it rather than assume it
Configuration is one thing; what actually reaches the browser is another, because a CDN, a proxy or a hosting panel may rewrite headers on the way out. The check is per-response, across the whole site:
for each response:
content-encoding present on text/*?
cache-control matches the asset class?
etag or last-modified on documents?
Run it after each deploy. This class of regression is silent — nothing breaks, the site just gets slower and the bill for bandwidth goes up — which is exactly why it survives for years when nobody looks.
Read next
Check how much of this is on your own site
A free scan surfaces broken links, JS errors and performance problems in about a minute.