# Cache e CDN: hit rate reale, misurato

Su 60 richieste al sito 40 sono state servite dal bordo (66,7%): gli asset statici fanno HIT 40 volte su 40, l'HTML 0 su 20. Il TTFB passa da 26 a 276 ms. Come si misura.

> Pagina: https://ui.eneawork.it/blog/performance-cache-cdn
> Markdown: https://ui.eneawork.it/blog/performance-cache-cdn.md

*2026-11-01*

Su 60 richieste misurate al sito 40 sono state servite dalla cache edge, il 66,7%: tutte le 40 statiche hanno fatto HIT, tutte le 20 di HTML hanno fatto DYNAMIC. Il TTFB mediano passa da 26-34 ms per gli asset a 256-276 ms per l'HTML.

Dieci richieste per ciascuna di sei URL (home, articolo, CSS, font, immagine, icona) eseguite il 1 novembre 2026 dallo stesso client, senza header di cache nella richiesta e con il corpo letto per intero: 60 richieste, 40 HIT (66,7%), 40 su 40 per gli asset statici, 0 su 20 per l'HTML, che risponde cf-cache-status: DYNAMIC e Cache-Control: no-cache. TTFB mediano: 26 ms per il CSS, 34 ms per il font, 30 ms per l'immagine, 276 ms per la home. Comando: il ciclo curl qui sotto, ripetuto dieci volte per sei URL. Age del CSS: 83.580 s. Catalogo: 111.985 componenti, 1.556 blocchi, 12.808 icone da 1.472 librerie, letti da /api/stats il 1 novembre 2026. Soglie: web.dev, CC BY 4.0.

## Cosa risponde il bordo

La differenza tra 30 e 276 ms è il costo dell'origine: l'HTML viene generato a ogni richiesta, gli asset arrivano dal bordo. Non è un difetto della CDN, è una decisione: l'HTML cambia spesso e non ha una chiave di cache stabile.

## Misurarlo da terminale

for u in / /blog/core-web-vitals-ttfb /css/components-ui.css \ /fonts/inter-400-latin.woff2; do printf '%s ' "$u" curl -sI "https://ui.eneawork.it$u" | grep -i -E '^(cf-cache-status|age|cache-control):' | tr '\n' ' ' echo done

Il comando stampa stato della cache, età dell'oggetto e politica di cache per ogni URL. Age dice da quanti secondi il bordo ha quella copia: 83.580 s per il CSS, cioè quasi un giorno.

## La query string entra nella chiave

Con una URL nuova (?probe=...) la prima risposta è MISS e la seconda è HIT: il parametro fa parte della chiave. Un identificatore di campagna diverso per utente azzera la cache su ogni visita, e lo stesso vale per un parametro di ordinamento nei link interni.

## Cosa cambiare

## Il limite da dichiarare

La misura viene da un solo client e da un solo punto di presenza (Milano, dal CF-RAY), con dieci richieste per URL. L'hit rate reale dipende dal traffico, dalla distribuzione geografica e dai TTL: un sito con molte pagine HTML e pochi asset mostra una percentuale molto più bassa, perché il 66,7% qui mescola due popolazioni diverse.

## Dove continuare

Il catalogo EneUI indicizza 111.985 componenti, per esempio card-stack, e la griglia di 1.556 blocchi: ogni record è una pagina HTML che non finisce in cache edge. Leggi come si misura il TTFB, la cache con un service worker e come si fissa un performance budget.

## FAQ

### Che cos'è il cache hit rate?

È la percentuale di richieste servite dalla cache invece che dall'origine. Nel nostro campione è 66,7% complessivo e 100% sui soli asset statici.

### Perché l'HTML non viene messo in cache?

Perché risponde con Cache-Control: no-cache e cf-cache-status DYNAMIC. Il contenuto cambia spesso e il bordo non ha una chiave stabile per riusarlo.

### Come si legge cf-cache-status?

HIT vuol dire servito dal bordo, MISS vuol dire richiesta all'origine con salvataggio, DYNAMIC vuol dire non cacheabile con le regole attuali, EXPIRED vuol dire copia scaduta.

### Il TTFB di un HIT è sempre basso?

Dipende dalla distanza dal punto di presenza. Qui 26-34 ms dal bordo contro 256-276 ms dall'origine, misurati dallo stesso client.

### La query string rompe la cache?

Sì, se fa parte della chiave. Una URL con un parametro nuovo è un oggetto nuovo: la prima richiesta è MISS, la seconda HIT.
