넥스트JS의 서버 캐싱 3종 비교: cache, unstable_cache, unstable_noStore

김현준·2025년 5월 14일

넥스트JS

목록 보기
7/8

넥스트js의 확장된 fetch는 서버 데이터 캐싱과 무효화 전략을 유연하게 구성할 수 있게 되었다.

  • cache()는 렌더링 중 최적화,
  • unstable_cache()는 서버 캐시 + ISR + 태그 무효화,
  • unstable_noStore()는 최신 데이터 보장을 위한 무조건 재요청용

한 줄 정리

  • cache()

    • 목적: 리액트 서버 렌더링 중 중복 호출을 막기 위한 메모이제이션
    • 사용위치: 리액트 서버 컴포넌트
  • unstable_cache()

    • 목적: 넥스트js 서버 캐시 + 태그/경로 무효화가 가능한 고급 캐싱 도구
    • 사용위치: RSC, Route Handler, Server Action
  • unstable_noStore()

    • 목적: 매 요청마다 강제 fetch (절대 캐싱 안 함)
    • 사용위치: 동일

비교 표

항목cache() (React)unstable_cache() (Next.js)unstable_noStore() (Next.js)
제공 주체ReactNext.jsNext.js
캐싱 범위같은 렌더링 중요청 간에도 재사용 (Persistent)없음 (항상 새로 요청)
캐시 지속시간1 요청 단위서버 글로벌 캐시없음
태그 무효화불가능가능 (revalidateTag)없음
revalidate 설정없음가능 (revalidate: 60 등)없음
SSR/ISR 캐싱 통합없음가능없음
사용 대상단순 메모이제이션 (e.g. getPost)페이지/데이터 fetch, DB민감하거나 최신 상태 필요할 때
클라에서 사용 가능?불가능불가능불가능

사용 예시

cache() 예시 (RSC 내부 메모이제이션)

// getPost.ts
import { cache } from 'react';

export const getPost = cache(async (id: string) => {
  return await db.post.findUnique({ where: { id } });
});
  • rkx은 요청 중 layout.tsx, metadata.tsx, page.tsx가 getPost(id)를 중복 호출해도 1회만 실행됨

unstable_cache() 예시 (Next.js 서버 캐시)

import { unstable_cache } from 'next/cache';

const fetchPopularPosts = unstable_cache(
  async () => await db.post.findMany({ where: { popular: true } }),
  ['popular-posts'],
  { tags: ['posts'], revalidate: 3600 }
);
  • 서버 캐시에 저장됨
  • /api/revalidate에서 revalidateTag('posts')로 수동 무효화 가능
  • revalidate를 통해 SSG/ISR처럼 설정 가능

unstable_noStore() 예시 (캐싱 완전 비활성화)

import { unstable_noStore } from 'next/cache';

export async function getUser() {
  unstable_noStore(); // 이 함수 내 모든 fetch, DB는 캐싱하지 않음
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();
  return user;
}
  • 유저 정보 등 매 요청마다 최신 데이터가 필요한 민감한 정보에 적합

어떤 걸 언제 써야 할까?

상황추천 함수이유
서버 렌더링 중 같은 데이터 여러 곳에서 쓰임cache()render 단위 중복 방지
인기글, 페이지 데이터 등 태그 무효화로 관리하고 싶음unstable_cache()캐시 태그 + ISR까지 가능
로그인 유저 정보처럼 절대 캐시되면 안 되는 민감한 데이터unstable_noStore()요청마다 DB를 새로 조회하게 강제
profile
기록하자

0개의 댓글