본문 바로가기
카테고리 없음

[React Query] 데이터 패칭 최적화: staleTime과 cacheTime의 미묘한 차이 이해하기

by 돌미나리는야생미나리 2026. 4. 27.

서버 상태 관리 라이브러리의 표준이 된 React Query. 그 핵심 기능은 단연 '캐싱'입니다. 하지만 설정을 들여다보면 staleTime과 cacheTime이라는 비슷해 보이는 두 가지 옵션이 우리를 혼란스럽게 합니다.

"둘 다 시간 설정 같은데, 하나만 쓰면 안 되나?", "왜 캐시 타임을 늘렸는데 데이터가 계속 새로고침 되지?" 이런 의문을 가져보셨다면 오늘 글이 완벽한 해답이 될 것입니다. 이 두 지표의 메커니즘을 이해하는 것은 효율적인 프런트엔드 성능 최적화의 첫걸음입니다.


1. 데이터의 상태: Fresh vs Stale

본격적인 비교에 앞서, 리액트 쿼리가 데이터를 바라보는 두 가지 상태를 이해해야 합니다.

  • Fresh (신선한 상태): 서버에서 막 가져온 데이터입니다. 이 상태에서는 컴포넌트가 다시 마운트되어도 추가적인 네트워크 요청을 보내지 않습니다.
  • Stale (탁한/상한 상태): 가져온 지 일정 시간이 지나 '신선하지 않다'고 판단된 데이터입니다. 이 상태의 데이터는 컴포넌트가 마운트 되거나 윈도가 포커스 될 때 백그라운드에서 다시 요청(Refetch)됩니다.

2. staleTime: "이 데이터는 언제까지 신선한가?"

staleTime은 데이터를 Fresh 상태에서 Stale 상태로 변경하는 데 걸리는 시간입니다.

2.1 동작 원리

  • 데이터를 처음 가져오면 즉시 Fresh 상태가 됩니다.
  • staleTime이 5분(300,000ms)이라면, 5분 동안은 컴포넌트가 몇 번을 리렌더링 되거나 다시 마운트 되어도 서버에 요청을 보내지 않습니다.
  • 5분이 지나면 데이터는 Stale 상태가 됩니다. 이때부터는 컴포넌트가 마운트될 때마다 서버에 "최신 데이터 맞니?"라고 물어보게 됩니다.

2.2 실무 팁

자주 바뀌지 않는 공지사항이나 설정 데이터는 staleTime을 길게(예: 1시간) 잡는 것이 서버 부하를 줄이는 데 매우 효과적입니다. 반면 주식 시세나 실시간 채팅은 0으로 설정하여 항상 최신 상태를 유지해야 합니다. (기본값은 0입니다.)


3. gcTime (과거 cacheTime): "메모리에 얼마나 남겨둘 것인가?"

Next.js나 최신 버전의 React Query(v5)에서는 cacheTime이 gcTime (Garbage Collection Time)으로 이름이 바뀌었습니다. 이름에서 알 수 있듯, 이는 데이터를 메모리에서 완전히 삭제(청소)하기까지의 시간입니다.

3.1 동작 원리

  • 데이터를 사용하는 모든 컴포넌트가 언마운트되어 '비활성(Inactive)' 상태가 된 순간부터 타이머가 돌아갑니다.
  • 기본값인 5분(300,000ms) 동안 사용되지 않으면, 리액트 쿼리는 메모리 절약을 위해 해당 데이터를 삭제합니다.
  • 데이터가 삭제되기 전에 다시 컴포넌트가 마운트 되면, 서버 응답을 기다리는 동안 메모리에 남아있던 '캐시 데이터'를 먼저 보여주어 사용자 경험을 높입니다.

4. 결정적 차이: 쟁점은 '네트워크 요청'인가 '메모리 삭제'인가

두 개념을 한 문장으로 정리하면 다음과 같습니다.

staleTime은 다시 요청(Refetch)할 것인가를 결정하고, gcTime은 메모리에서 지울 것인가를 결정합니다.

4.1 시나리오로 이해하기

설정: staleTime: 2분, gcTime: 5분

  1. 0분: 데이터 패칭 완료. 데이터는 Fresh 상태.
  2. 1분: 페이지 이동으로 컴포넌트 언마운트. 데이터는 Inactive 상태가 되며 gcTime 타이머 시작.
  3. 3분: 다시 컴포넌트 마운트.
    • staleTime(2분)이 지났으므로 데이터는 Stale 상태입니다. -> 네트워크 요청 발생.
    • gcTime(5분)은 아직 안 지났으므로 메모리에 데이터가 남아있습니다. -> 서버 응답 전까지 이전 데이터를 화면에 즉시 보여줌 (Flash of old content).
  4. 6분: 컴포넌트 마운트.
    • gcTime이 지났으므로 메모리에 데이터가 없습니다. -> 로딩 스피너를 보여주며 새로 가져옴.

5. 실무 최적화 전략: 어떻게 설정하는 것이 베스트인가?

5.1 staleTime < gcTime (권장 패턴)

가장 일반적인 설정입니다. 메모리에는 데이터를 남겨두어 로딩 속도를 높이되, 일정 시간이 지나면 서버에서 최신화를 시도하는 방식입니다.

5.2 staleTime > gcTime (의미 없는 설정)

만약 데이터를 신선하다고 생각해서 요청을 안 하려는데(staleTime 10분), 메모리에서 이미 지워버렸다면(gcTime 2분), 결국 다시 서버에서 가져와야 하므로 최적화 효과가 사라집니다. 항상 gcTime은 staleTime보다 길거나 같아야 합니다.