HTTP 캐시는 응답을 저장해 뒀다가 동일 요청에 재사용함으로써 지연·대역폭·서버 부하를 줄이는 표준 메커니즘입니다.
브라우저(개인 캐시)부터 CDN·리버스 프록시(공유 캐시)까지 여러 계층에 존재하며, 응답 헤더로 정밀하게 제어됩니다.
핵심은 '신선도(freshness)'와 '재검증(revalidation)' 두 단계입니다. `Cache-Control: max-age=600`처럼 신선 기간 동안은 네트워크 요청 없이 캐시를 그대로 쓰고(=가장 빠름), 만료되면 `ETag`/`Last-Modified`를 조건부 헤더로 보내 서버에 '바뀌었나?'를 확인합니다. 안 바뀌었으면 `304`로 본문을 다시 받지 않습니다. 주요 지시어로 `no-store`(저장 금지), `no-cache`(저장하되 매번 재검증), `private`(개인 캐시만), `public`(공유 캐시 허용), `immutable`, `stale-while-revalidate`가 있습니다.
실무 패턴이 중요합니다. 해시가 파일명에 박힌 정적 자산(app.9f3a.js)은 `max-age=31536000, immutable`로 사실상 영구 캐시하고, HTML은 자주 바뀌므로 `no-cache`로 매번 재검증하게 하는 조합이 흔합니다. 흔한 사고는 공유 캐시(CDN)에 개인화·인증 응답을 `public`으로 흘려 다른 사용자에게 노출되는 것이므로, 사용자별 응답에는 `private`/`no-store`를 신중히 지정합니다. 캐시 갱신이 필요할 땐 CDN purge와 파일명 버저닝을 병행해 '오래된 콘텐츠' 문제를 예방합니다.