Devliner

Next.js use cache와 cacheLife로 캐시 수명을 설계하는 방법

Next.js use cache와 cacheLife로 캐시 수명을 설계하는 방법 대표 이미지

도입: 캐시 수명 설계의 목표와 한 줄 답

Next.js의 use cache 지시자와 cacheLife 함수를 사용하면 함수나 컴포넌트의 캐시 수명을 명시적으로 제어할 수 있다. use cache로 캐싱 대상을 지정하고, cacheLife로 재검증 주기와 만료 시간을 설정하는 것이 핵심이다.

Next.js use cache와 cacheLife의 핵심 항목

1. use cache 지시자 적용

준비

  • Next.js 15 이상 버전 설치
  • next.config.js에서 실험적 기능 활성화: experimental: { dynamicIO: true }
  • 캐싱하려는 비동기 함수 또는 컴포넌트 파일 준비

단계

  1. 파일 최상단에 "use cache" 문자열 추가
  2. 함수가 비동기(async)인지 확인
  3. 서버 환경에서 실행되는 코드인지 확인 (클라이언트 컴포넌트는 적용 불가)
"use cache";

export async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  return response.json();
}

주의점

  • 클라이언트 컴포넌트("use client")와 동시 사용 불가
  • 동기 함수에는 적용되지 않음
  • 파일 단위로 적용되므로 모듈 내 모든 export가 영향 받음

완료 기준

  • 빌드 시 캐시 관련 경고나 오류가 없음
  • 개발 서버에서 함수 호출 시 중복 요청이 발생하지 않음

2. cacheLife 함수로 수명 정의

준비

  • next/cache에서 cacheLife 함수 import
  • 캐시 정책 이름과 시간 단위 결정 (초 단위)
  • revalidate(재검증 주기)와 expire(만료 시간) 값 계획

단계

  1. cacheLife 함수를 캐싱 함수 내부 최상단에서 호출
  2. 정책 이름을 첫 번째 인자로 전달
  3. 옵션 객체에 revalidate와 expire 값 설정
"use cache";
import { cacheLife } from 'next/cache';

export async function getProducts() {
  cacheLife('products', {
    revalidate: 3600,
    expire: 86400
  });
  
  const data = await fetch('https://api.example.com/products');
  return data.json();
}

주의점

  • revalidate는 백그라운드에서 데이터를 갱신하는 주기
  • expire는 캐시가 완전히 삭제되는 시간
  • expire는 revalidate보다 크거나 같아야 함
  • 시간 단위는 초(seconds)

완료 기준

  • 설정한 revalidate 시간 이후 백그라운드 갱신 발생
  • expire 시간 이후 캐시가 삭제되고 새 요청 시 재생성
  • 타입 검사 통과

3. 전역 캐시 프로필 구성

준비

  • next.config.js 파일 접근 권한
  • 애플리케이션 전체에 적용할 캐시 정책 목록
  • 각 정책별 revalidate/expire 값 설계

단계

  1. next.config.js의 experimental.cacheLife 객체 추가
  2. 정책 이름을 키로, 시간 설정을 값으로 지정
  3. 기본 정책 재정의 가능 (default, seconds, minutes 등)
module.exports = {
  experimental: {
    dynamicIO: true,
    cacheLife: {
      frequent: {
        revalidate: 60,
        expire: 300
      },
      daily: {
        revalidate: 3600,
        expire: 86400
      }
    }
  }
};

주의점

  • 설정 변경 후 개발 서버 재시작 필요
  • 프로필 이름은 함수 내 cacheLife 호출 시 첫 번째 인자와 일치해야 함
  • 전역 설정보다 함수 내 직접 설정이 우선순위 높음

완료 기준

  • 서버 재시작 후 설정이 반영됨
  • 정의한 프로필 이름으로 함수 내에서 호출 가능
  • 여러 함수에서 동일 프로필 재사용 가능

전체 실행 순서

  1. Next.js 15 이상 설치 및 dynamicIO 실험 기능 활성화
  2. next.config.js에서 전역 캐시 프로필 정의 (선택)
  3. 캐싱할 서버 함수 파일 최상단에 "use cache" 추가
  4. 함수 내부에서 cacheLife 호출로 수명 설정
  5. 빌드 또는 개발 서버 실행으로 동작 확인
  6. 네트워크 탭이나 로그로 캐시 적중률 모니터링

주의점과 실패하기 쉬운 지점

지시자 위치 오류

"use cache" 문자열은 파일의 첫 줄 또는 import 구문 다음에 위치해야 한다. 함수 내부나 중간에 배치하면 무시된다.

시간 단위 혼동

revalidate와 expire는 밀리초가 아닌 초 단위다. 1시간은 3600, 1일은 86400이다.

클라이언트 컴포넌트 충돌

"use client"와 "use cache"는 동일 파일에 공존할 수 없다. 클라이언트 컴포넌트에서 캐싱이 필요하면 별도 서버 함수로 분리해야 한다.

동기 함수 적용 시도

use cache는 비동기 함수에만 작동한다. async 키워드가 없으면 캐싱되지 않는다.

expire < revalidate 설정

만료 시간이 재검증 주기보다 짧으면 논리적 모순이 발생한다. expire는 항상 revalidate 이상이어야 한다.

환경 변수 의존성

캐싱 함수가 환경 변수에 의존하면 빌드 시점과 런타임 값이 달라질 수 있다. 캐시 키에 환경별 구분자를 포함하거나 동적 렌더링으로 전환해야 한다.

완료 확인 체크리스트

  • [ ] Next.js 15 이상 설치 완료
  • [ ] next.config.js에 experimental.dynamicIO: true 설정
  • [ ] 캐싱 대상 파일 최상단에 "use cache" 추가
  • [ ] 함수가 async로 선언됨
  • [ ] cacheLife 함수 호출로 revalidate/expire 설정
  • [ ] expire >= revalidate 조건 충족
  • [ ] 빌드 시 캐시 관련 오류 없음
  • [ ] 개발 서버에서 중복 요청 감소 확인
  • [ ] 설정한 시간 이후 캐시 갱신 동작 확인
  • [ ] 프로덕션 빌드에서 정상 작동 검증

참고 자료

  • Nextjs
  • use
  • cache와

관련 글

전체 보기