노트

staleTime과 gcTime

staleTime and gcTime

프론트엔드#react#performance · 연결된 개념 4개

쉽게 말하면

staleTime은 '이 반찬을 얼마 동안 다시 안 사도 되나', gcTime은 '아무도 안 먹는 반찬을 언제 버리나'를 정하는 손잡이예요. 냉장고에서 신선도와 공간을 따로 관리하는 셈이죠.

비유의 한계 냉장고와 달리 stale이 돼도 바로 버리지 않고 먼저 보여 주고 백그라운드에서 다시 받아요. gcTime 시계도 stale 이후가 아니라 쓰는 컴포넌트가 0개인 inactive가 된 뒤부터 돌아요.

TanStack Query에서 staleTime은 받아 온 데이터를 얼마 동안 신선하다고 볼지(다시 요청할지)를, gcTime(Garbage Collection Time)은 아무도 쓰지 않는 캐시를 얼마 동안 메모리에 둘지(언제 지울지)를 정한다. 같은 캐시에 대한 서로 다른 두 손잡이다.

staleTimegcTime
관심사신선도 → 재요청 여부메모리 → 캐시 삭제
시계가 도는 때데이터를 받은 직후부터쿼리가 inactive(구독 컴포넌트 0개)가 된 뒤부터
기본값0(받자마자 stale)5분
stateDiagram-v2
  state "fresh" as F
  state "stale (캐시엔 있음)" as S
  state "inactive (구독 컴포넌트 0개)" as I
  [*] --> F: 마운트 → fetch
  F --> S: staleTime 경과
  S --> F: 트리거 시 백그라운드 재요청
  F --> I: 언마운트
  S --> I: 언마운트
  I --> [*]: gcTime 경과 → 캐시에서 삭제
  • fresh한 동안에는 재마운트나 창 포커스가 와도 요청하지 않는다. 기본값 0은 "왜 안 바뀌지?"보다 "항상 갱신"이 낫다는 판단이다
  • 이름: v4까지 cacheTime이었고 v5에서 gcTime으로 바뀌었다. 그리고 gcTime은 stale이 된 뒤가 아니라 inactive가 된 뒤 시작된다
  • 실무에서 주로 만지는 것은 staleTime이다. 잘 안 바뀌는 데이터(카테고리, 설정)는 길게 잡는다
  • gcTime을 만지는 경우
    • 한참 뒤 돌아와도 즉시 이전 화면을 보여 주고 싶을 때(길게)
    • 데이터가 크거나 다시 볼 일이 없을 때(짧게)
    • 민감한 데이터를 화면을 떠나면 바로 지우고 싶을 때(0)
    • 캐시를 localStorage 등에 영속화할 때(길게)
  • staleTime이 gcTime보다 길면 의미가 줄어든다. 아직 fresh인데 캐시가 지워져 버릴 수 있어서 보통 gcTime ≥ staleTime으로 둔다

HTTP(HyperText Transfer Protocol) 쪽의 같은 아이디어는 브라우저 캐시의 max-age·stale-while-revalidate, ISR(Incremental Static Regeneration)의 재생성 주기(CSR·SSR·SSG·ISR)다. 전체 흐름은 TanStack Query.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 스텁 큐

    서드파티 SDK 본체가 아직 로드되지 않았을 때, 작은 스텁(stub)이 들어온 호출을 배열에 쌓아 두고 본체가 도착하면 쌓인 호출을 순서대로 처리하는 방식. Google Tag Manager(GTM)의 dataLayer와 gtag.js의 gtag()가 이 구조이고, Meta Pixel의 fbq() 설치 코드도 본체 전 호출을 배열에 쌓는다. 쌓아 두는 배열은 먼저 들어온 것부터 꺼내는 큐로 쓰인다.

  • 최종 일관성

    최종 일관성(eventual consistency)은 "지금 당장은 저장소마다 값이 다를 수 있지만, 새 변경이 멈추면 결국 같아진다"는 보장이다. 원본 DB와 검색 색인·캐시·다른 서비스처럼 물리적으로 분리된 저장소를 한 트랜잭션으로 묶을 수 없을 때 받아들이는 일관성 모델(consistency model)이다.

  • "use cache"와 Cache Components

    'use cache'는 Next.js 16의 Cache Components 모델에서 async 함수나 컴포넌트의 반환값을 캐시하라고 명시하는 지시어(Directive)다. 아무것도 표시하지 않으면 매 요청 실행되고, 캐시하고 싶은 곳에만 직접 붙인다(옵트인, Opt-in).

  • LRU 캐시와 캐시 계층 비교

    LRU(Least Recently Used) 캐시는 크기를 정해 두고, 가득 차면 가장 오랫동안 쓰지 않은 항목부터 버리는 메모리 캐시다. Node.js에서는 lru-cache 패키지가 대표적이다. 자주 쓰는 데이터는 계속 남고 안 쓰는 것만 밀려난다.

  • 롱 태스크

    메인 스레드를 50ms 넘게 붙잡는 작업. W3C Long Tasks 명세는 이벤트 루프 태스크(뒤따르는 마이크로태스크 처리 포함), 렌더링 갱신 단계, 이벤트 루프 밖에서 브라우저가 UI 스레드로 하는 일 가운데 50ms를 넘는 것을 롱 태스크로 본다. 태스크는 도중에 끊기지 않으므로 그동안 클릭·키 입력 처리와 화면 갱신이 모두 밀린다(이벤트 루프).

보기 옵션