쿠키가 보이면 캐시가 무조건 꺼질 것 같죠? 사실은 쿠키가 있다는 사실만으로 HTTP 캐시 가능성이 자동으로 끝나지는 않아요.CDN, Cache, 그리고 Edge Delivery에서는 캐시가 사용자 가까이에 복사본을 두는 큰 그림을 봤어요. 그리고 Cache Key와 Vary에서는 같은 URL이라도 요청 헤더나 쿠키 조건 때문에 사본이 나뉠 수 있다는 감각을 잡았죠. 이번에는 캐시 문제에서 가장 조심스러운 신호를 볼게요.
“쿠키가 있으니까 당연히 캐시 안 되겠죠?”그런데 이 단정이 위험해요.
Cookie 요청 헤더와 Set-Cookie 응답 헤더가 있다고 해서 HTTP 표준상 캐시 저장과 재사용이 자동으로 금지되는 건 아니거든요. 캐시 가능성과 재사용의 직접 기준은 RFC 9111: HTTP Caching이고, 이 문서는 Set-Cookie 응답 헤더가 캐싱을 막지 않는다고 설명해요. RFC 6265: HTTP State Management Mechanism은 Cookie와 Set-Cookie가 사용자 상태를 어떻게 전달하고 저장하는지 설명하는 쿠키 의미의 기준 문서예요.
그래서 오늘 질문은 이거예요.
“이 응답은 여러 사용자가 같이 써도 되는 사본일까요, 아니면 한 사용자에게만 묶어야 하는 사본일까요?”
여기서는 쿠키 문법 전체보다 쿠키가 캐시 가능성 판단에 어떤 신호로 들어오는지에 집중해요. 실제 CDN은
Set-Cookie가 있으면 우회하거나, 쿠키를 제거하고 저장하거나, 특정 쿠키만 cache key에 넣는 제품별 정책을 가질 수 있어요. 그래서 표준 원칙과 CDN 설정을 함께 봐야 해요.같은 도시락처럼 보여도 이름표가 붙으면 조심해야 해요
회사 탕비실에 도시락이 놓여 있다고 해볼게요.- 아무나 먹어도 되는 공용 샌드위치가 있어요.
- 특정 사람 이름이 붙은 도시락도 있어요.
- 겉포장은 비슷하지만, 안쪽에는 알레르기나 식단 옵션이 다를 수 있어요.
- 이름표가 붙은 도시락을 공용 선반에 두면 누군가 잘못 가져갈 수 있어요.
핵심은 쿠키가 사용자 상태와 관련된 강한 힌트라는 점이에요. 하지만 쿠키가 보인다고 무조건 버리는 게 아니라, 이 응답이 정말 사용자별인지, 공용으로 재사용해도 되는지, 저장 자체를 피해야 하는지 나눠 읽어야 해요.
이 그림에서 먼저 묻는 질문은 “쿠키가 있나요?”가 아니에요. “응답이 누구에게나 같아도 되나요?” 가 먼저예요.
Cookie와 Set-Cookie는 서로 다른 방향의 신호예요
쿠키를 볼 때는 요청과 응답을 나눠야 해요.Cookie는 클라이언트가 서버에게 보내는 요청 헤더예요. 브라우저가 “저는 이런 상태를 가지고 있어요”라고 알려주는 쪽이죠.
Set-Cookie는 서버가 브라우저에게 보내는 응답 헤더예요. “다음 요청부터 이 값을 들고 오세요”라고 저장시키는 쪽이고요.
여기서 중요한 반전이 있어요.
“Set-Cookie가 있으니 표준 캐시는 절대 저장하지 않을 것이다.”
그렇게 기대하면 안 돼요. 민감한 응답이라면 서버가 명시적으로 Cache-Control: private이나 Cache-Control: no-store 같은 정책을 줘야 해요. CDN 제품이 보호적으로 우회해줄 수도 있지만, 그건 제품 정책이지 HTTP 표준의 자동 안전장치로 보면 안 돼요.
사용자별 응답은 공유 캐시에 섞이면 안 돼요
가장 위험한 장면부터 볼게요.
처음에는 이렇게 나누면 좋아요.
private보다 더 강한 요구가 필요할 수 있어요.
쿠키가 있어도 공용 응답일 수 있어요
반대로 쿠키가 있다고 항상 사용자별 응답은 아니에요. 예를 들어 사용자가 로그인한 상태로 공용 CSS 파일을 요청할 수 있어요.Cookie가 붙었다는 이유만으로 CDN이 매번 오리진으로 보내면 캐시 효율이 크게 떨어져요.
그래서 실제 운영에서는 이런 전략을 자주 검토해요.
쿠키가 응답을 바꾼다면 그 차이를 캐시가 구분해야 해요. 하지만 아래처럼 쿠키 전체를 비교 대상으로 삼으면 범위가 너무 넓을 수 있어요.
Vary와 어떻게 맞추는지는 Cache Key와 Vary는 왜 같이 읽어야 할까요?에서 이어서 볼게요.
Authorization은 더 보수적으로 읽어요
쿠키와 비슷하게 인증된 요청을 만드는 헤더가 있어요.public, s-maxage, must-revalidate 같은 명시적인 지시가 있으면 예외적으로 공유 캐시에 저장될 수 있는 길이 열려요.
그래서 인증 API를 볼 때는 이렇게 묻는 게 좋아요.
디버깅할 때는 여섯 줄을 같이 봐요
쿠키와 캐시가 얽힌 문제는 한 줄만 보면 거의 틀려요. 요청과 응답을 같이 놓고 봐야 해요.
여기서
CF-Cache-Status: MISS가 보인다고 바로 문제라고 보면 안 돼요. 첫 요청이라 MISS일 수도 있고, 쿠키 때문에 key가 달라졌을 수도 있고, 제품 정책상 Set-Cookie 응답을 우회했을 수도 있어요.
중요한 건 이 질문이에요.
“이 MISS는 안전을 위한 의도된 우회인가요, 아니면 캐시할 수 있는 공용 응답을 쿠키 때문에 놓친 건가요?”
잘못 읽기 쉬운 함정
1. “쿠키가 있으면 무조건 캐시되지 않는다”
표준 관점에서는 그렇게 단순하지 않아요.Cookie나 Set-Cookie가 있어도 캐시 가능한 응답이 있을 수 있어요. 안전하게 막아야 한다면 Cache-Control과 CDN 정책으로 명시해야 해요.
2. “Set-Cookie가 있으니 사용자별 응답이다”
항상 그렇지는 않아요. 팝업을 봤다는 표시, 실험 배정, 분석용 쿠키처럼 본문이 모두에게 같은 응답에도Set-Cookie가 붙을 수 있어요. 다만 공유 캐시가 그 헤더를 어떻게 다루는지는 제품별로 확인해야 해요.
3. “Vary: Cookie면 안전하다”
Vary: Cookie는 쿠키 값이 다르면 사본을 나누라는 신호예요. 하지만 민감한 사용자 응답을 공유 캐시에 저장해도 된다는 허가증은 아니에요. 게다가 쿠키 전체를 기준으로 나누면 히트율이 크게 떨어질 수 있어요.
4. “private이면 아무 데도 저장되지 않는다”
private은 공유 캐시가 재사용하면 안 된다는 신호에 가까워요. 브라우저 같은 개인 캐시는 저장할 수 있어요. 저장 자체를 피해야 하는 민감 응답이라면 no-store를 봐야 해요.
5. “CDN 상태 헤더 하나로 원인을 알 수 있다”
HIT, MISS, BYPASS, DYNAMIC은 결과 신호예요. 이유는 Cache-Control, 쿠키, 인증 헤더, cache key, CDN 규칙, 오리진 응답을 같이 봐야 보여요.
예시로 같이 읽어볼게요
1. 정적 파일에 쿠키가 따라온 경우
max-age, immutable, Vary: Accept-Encoding이 서로 말이 맞는지 봐요. 정적 자산 요청에 세션 쿠키가 붙지 않도록 쿠키 scope나 정적 도메인을 정리하면 캐시 효율이 더 좋아질 수 있어요.
2. 계정 페이지가 public으로 내려온 경우
/account가 사용자별 본문이라면 공유 캐시가 재사용하면 안 돼요. private 또는 no-store, CDN bypass 규칙, 프레임워크의 기본 캐시 헤더를 같이 확인해야 해요.
3. 실험 그룹별 랜딩 페이지
Vary: Cookie는 너무 넓을 수 있어요. 어떤 값만 구분할지는 Cache Key와 Vary의 기준으로 확인해요.
4. 토큰 API 응답
no-store가 빠졌다면 프레임워크, 게이트웨이, CDN 기본 정책까지 같이 확인해야 해요.
자, 정리해볼까요?
Cookie는 요청의 사용자 상태 신호이고, Set-Cookie는 응답이 브라우저에 상태를 저장시키는 신호예요.쿠키가 있다는 사실만으로 HTTP 캐시 가능성이 자동으로 사라지는 것은 아니에요.사용자별 응답은 공유 캐시에 섞이면 안 되므로 private, no-store, CDN bypass 같은 명시 정책이 필요해요.공용 정적 파일이나 공용 페이지는 쿠키가 따라와도 캐시 가능할 수 있지만, 실제로 응답이 모두에게 같은지 확인해야 해요.Vary: Cookie는 안전 만능키가 아니고, 쿠키 전체를 기준으로 삼으면 히트율이 크게 떨어질 수 있어요.디버깅할 때는 요청의 Cookie와 Authorization, 응답의 Cache-Control, Set-Cookie, Vary, CDN 상태 헤더를 한 화면에서 같이 봐야 해요.이어서 보면 좋은 글
- CDN, Cache, 그리고 Edge Delivery — 공유 캐시와 엣지 전달의 큰 그림으로 돌아가고 싶을 때 좋아요.
- Cache Key와 Vary는 왜 같이 읽어야 할까요? — 같은 URL이어도 쿠키와 요청 헤더 때문에 사본이 어떻게 나뉘는지 이어서 볼 수 있어요.
- CDN Cache Status 헤더는 어떻게 읽어야 할까요? — 쿠키 때문에
MISS,BYPASS,DYNAMIC처럼 보일 때 주변 헤더와 같이 읽어봐요. - stale-while-revalidate와 soft purge는 왜 같이 볼까요? — 캐시된 사본이 오래됐을 때 언제 보여주고 언제 갱신할지 이어서 볼 수 있어요.