Next.js 캐싱 완전 정리 — 4층 캐시
같은 데이터가 4번 캐시될 수 있다. 4층의 위치와 폐기 방법.
Next.js 가 가장 헷갈리는 이유 중 하나 — 같은 데이터가 동시에 4곳에 캐시된다. 무효화하면 한 곳만 비는데 다른 곳에 옛 데이터가 남아 화면이 안 바뀐다. "분명 fetch 했는데 옛 값이 와요" 의 정체.
16편에서 ISR·SSG·SSR 모드 차이를 봤다면, 이번은 그 뒤에서 도는 실제 캐시 4층을 본다. 한 번 외워두면 디버깅이 한결 빨라진다.
1. 4층 캐시 한눈에
| 층 | 위치 | 수명 | 목적 |
|---|---|---|---|
| Request Memoization | 서버 · 한 요청 내 | 요청 끝나면 폐기 | 같은 요청에서 fetch 중복 제거 |
| Data Cache | 서버 · 영구 (지정 시간) | revalidate 또는 폐기 호출 | fetch 결과 재사용 |
| Full Route Cache | 서버 · 영구 | revalidate 또는 재배포 | SSG·ISR HTML 통째 캐시 |
| Router Cache | 브라우저 메모리 | 세션 또는 5분 | 뒤로가기·페이지 전환 빠르게 |
요청이 들어오면 — 위에서 아래로 검사. Router Cache 에 있으면 즉시 응답, 없으면 Full Route Cache, 그 안에서 fetch 호출은 Data Cache, 같은 요청 내 중복은 Memoization. 4단 콤보.
2. Request Memoization — 자동 중복 제거
한 페이지 렌더링 중에 같은 fetch 가 여러 번 일어나는 경우.
두 컴포넌트가 같은 getUser() 를 부르지만 실제 fetch 는 한 번만. Next 가 자동으로 캐시해서 두 번째 호출에 그대로 돌려준다. React 의 cache() 함수 + fetch 자동 동작.
fetch 가 아닌 함수(db.query·axios)는 자동 안 됨. 그 경우 React 의 cache(fn) 으로 감싸 명시.
3. Data Cache — fetch 결과 영구 저장
16편에서 본 force-cache·revalidate 의 실제 동작층.
위치는 빌드된 서버 메모리 또는 디스크. Vercel 같은 서버리스 환경에선 사용자 가까운 엣지에 분산 저장. 같은 fetch 가 여러 요청에 걸쳐 재사용된다.
4. Full Route Cache — 페이지 통째 HTML
SSG·ISR 페이지가 캐시되는 위치. 빌드 타임에 HTML 을 만들어 디스크에 저장.
한 시간 동안은 같은 HTML 이 모든 사용자에게. 사용자 별로 다른 데이터를 보여줘야 하면 페이지에 cookies()·headers() 같은 동적 함수를 부르면 자동으로 Full Route Cache 비활성화.
5. Router Cache — 브라우저 메모리
유일하게 클라이언트 측 캐시. 사용자가 한 번 본 페이지를 다시 갈 때 즉시 보여주려고 React 가 메모리에 들고 있다.
예 — 블로그 목록 → 글 클릭 → 뒤로가기. 뒤로가기 시 서버 fetch 없이 즉시 목록 표시. 5분 또는 세션 동안 유효.
revalidatePath 호출했는데 클라이언트에선 옛 데이터가 보이는 현상. Router Cache 가 클라이언트 메모리에 남아 있어서. 강제 새로고침 또는 router.refresh() 호출로 폐기.
폐기 방법 — 4가지 도구
| 도구 | 대상 | 언제 |
|---|---|---|
revalidatePath('/posts') | 해당 경로의 Data + Full Route Cache | 글 발행 후 |
revalidateTag('posts') | 태그 붙은 모든 Data Cache | 여러 페이지에 영향 주는 글 수정 |
router.refresh() | 현재 페이지의 Router Cache | 클라이언트에서 서버 변경 반영 |
| 재배포 | 모든 빌드 캐시 | 스키마 변경·전면 갱신 |
Server Action 안에서 revalidatePath + 클라이언트에서 router.refresh() 가 같이 일어나야 진짜 깔끔한 갱신. 한 쪽만 하면 옛 데이터가 어디선가 남아 헷갈린다.
요약 — 17편 좌표
여기까지 정리. Next.js 캐싱 4층 — Request Memoization(요청 내), Data Cache(fetch 결과 영구), Full Route Cache(페이지 HTML 통째), Router Cache(브라우저 메모리). 위에서 아래로 검사. 폐기는 revalidatePath·revalidateTag·router.refresh·재배포 4가지. "옛 데이터가 보여요" 의 90% 가 Router Cache 또는 폐기 누락. 다음 편에서 환경변수로 비밀 설정.
다음 편 예고 — 환경변수 다루기
.env.local·NEXT_PUBLIC 규칙·실수 방지. 18편.