Next.js 15 캐싱 기본값 변경 정리 — fetch, Route Handler, Client Router Cache
무엇이 바뀌었나
Next.js 15에서 가장 큰 변화 중 하나는 캐싱의 기본값이 “캐시 안 함” 쪽으로 뒤집힌 점이다. 14까지는 서버 측 데이터 페칭이 기본적으로 캐시되는 방향이었고, 명시적으로 끄지 않으면 첫 요청 시점에 굳어버린 응답을 계속 돌려보낼 위험이 있었다. 15부터는 반대로, 명시적으로 켜야 캐시된다.
영향을 받는 영역은 크게 세 가지다.
- 서버 측
fetch()호출의 기본 캐싱 - App Router의 GET
Route Handler기본 캐싱 - 클라이언트 측
Router Cache의 페이지 세그먼트 보관 시간
각각이 별개의 설정이라, 마이그레이션할 때 한 곳만 손보면 다른 데서 의도치 않은 동작이 남는다는 점을 미리 알아두는 게 좋다.
fetch와 Route Handler
Next.js 14 시절의 fetch(url)은 옵션을 주지 않으면 cache: 'force-cache'로 작동했다. 15부터는 옵션을 주지 않으면 매 요청 새로 가져오는 동작이 기본이 된다. 외부 API가 자주 바뀌지 않아 기존에 캐시 효과를 보던 코드라면, 마이그레이션 후 응답 시간이 체감될 정도로 느려질 수 있다.
다시 캐시되게 하려면 두 가지 길이 있다.
- 호출부에서
fetch(url, { cache: 'force-cache' })또는next: { revalidate: 60 }같은 옵션을 명시 - 라우트 세그먼트에서
export const fetchCache = 'default-cache'를 선언해 그 라우트 안의 모든 fetch에 기본값을 적용
GET Route Handler도 같은 결로 바뀌었다. 기본이 동적 처리이고, 정적 응답으로 굳히고 싶다면 export const dynamic = 'force-static'을 라우트 파일에 추가해야 한다. POST·PUT 같은 메서드는 원래도 캐시되지 않았으므로 영향이 없다.
Client Router Cache
마지막은 클라이언트 측 캐시다. 페이지를 전환할 때 브라우저 메모리에 RSC payload가 잠시 보관되는데, 14에서는 이 보관 시간이 동적 페이지 30초, 정적 페이지 5분이었다. 15부터는 동적 페이지의 기본값이 0으로 바뀌어, 뒤로 가기로 돌아가도 새 요청이 나간다.
덕분에 데이터는 더 신선해지지만, 그만큼 서버 호출 횟수가 늘어날 수 있다. 예전 동작이 필요하면 next.config.js의 experimental.staleTimes로 직접 시간을 정할 수 있다.
module.exports = {
experimental: {
staleTimes: {
dynamic: 30,
static: 180,
},
},
};
세 변경 모두 “기본을 안전한 쪽으로 옮기고, 캐시는 의도적으로 켜라”라는 같은 방향이다. 마이그레이션할 때는 빌드 후 곧장 배포하지 말고, 외부 API 호출 횟수나 응답 시간 모니터링을 한 번 끼우는 편이 안전하다.