Tanstack Query ㅡ staleTime, gcTime 한 눈에 복기하기

작성자
현우
작성시각
수정시각
레퍼런스
Vacío
👀
한 눈에 확인해보자면 ..
staleTime : 이 데이터가 신선하다고 보는 시간
gcTime : 아무 컴포넌트가도 안쓰는 캐시를 메모리에 남겨놓는 시간

staleTime은 refetch를 할지 말지 영향을 주는 요소이다.

Q. 5분이라고 가정했을 때, 흐름은 아래와 같다.

0분 : 데이터 fetch
0 ~ 5분 : 데이터가 fresh한 상태
5분 이후 : stale 상태
fresh 상태에서는 같은 querykey로 다시 useQuery가 실행되어도 보통 네트워크 요청을 다시하지 않고, 캐시 데이터를 사용한다.

Q. 만약 5분이 지난 경우라면?

0분 : "/organizations" 진입 → API 요청
7분 : 다른 페이지 갔다가 다시 "/organizations" 진입
→ stale 상태
→ 기존 캐시 데이터 먼저 보여줄 수 있음
→ 백그라운드 refetch 가능

2. gcTime은 캐시를 언제 알게할지에 대한 영향을 주는 요소이다.

여기서 중요한 점은 gcTime은 쿼리가 inactive 된 순간부터 돌아간다.

active와 inactive의 차이점

active : 어떤 컴포넌트가 useQuery로 이 데이터를 사용 중
inactive : 아무 컴포넌트도 이 queryKey를 사용하지 않음
0분 : "/organization" 페이지 진입 → useQuery 사용 중 → active 상태
2분 : 다른 페이지로 이동 → useQuery 사라짐 → inactive 상태
12분 : inactive 된 지 10분이 지났고, 캐시 삭제
컴포넌트가 계속 마운트되어있으면 gcTime이 지나도 삭제되지 않으며, gcTime은 사용중인 데이터가 아니라 사용하지 않는 캐시에 대한 삭제 타이머이다.

3. staleTime과 gcTime을 같이 비교해보면 이렇게 정의할 수 있다.

먼저 useQuery에 아래와 같이 설정을 했다고 가정을 해보자.
staleTime: 5 * 60 * 1000 // 5분
gcTime: 10 * 60 * 1000 // 10분
다양한 예제로 확인을 해보면 쉽게 이해할 수 있다.

<예제 A> 3분 뒤에 들어옴

0분 : 목록 조회
1분 : 페이지 이탈 → inactive
3분 : 다시 진입
캐시 있음 → 바로 보여줌
staleTime 5분 안지남 → fresh 상태 → refetch 거의 안함

<예제 B> 7분 뒤 다시 들어옴

0분 : 목록 조회
1분 : 페이지 이탈 → inactive
7분 : 다시 진입
캐시 있음 → 바로 이전 데이터 보여줌
staleTime 지남 → stale 상태 → 백그라운드 refetch 가능

<예제 C> 12분 뒤 들어옴

0분 : 목록 조회
1분 : 페이지 이탈 → inactive
12분 : 다시 진입
inactive 된지 10분 넘음 → gcTime 지남 → 캐시 삭제됨 → 이전 데이터 없음 → 처음 로딩처럼 API 요청

4. staleTime만 길고, gcTime이 짧은 경우는 어떻게 될까?

useQuery에 아래와 같이 gcTime을 더 짧게 설정한 경우가 있다고 가정해보자.
staleTime: 30 * 60 * 1000 // 30분
gcTime: 5 * 60 * 1000 // 5분
6분 뒤 처음 조회했던 페이지에 다시 접근을 하는 상황을 상상해보았을 때 아래와 같다.
0분 : 데이터 목록 조회
1분 : 페이지 이탈 → inactive 상태
6분 : 다시 페이지 재진입
staleTime은 30분이라 아직 fresh였을 데이터지만, inactive 상태로 gcTime은 5분을 넘은 6분이 지났다. 그러면 메모리 상의 캐시는 삭제되고 다시 API를 요청하는 꼴이 된다.
그래서, 보통은 gcTime >= staleTime으로 권장되며 보통 이렇게 사용한다.
staleTime은 컴포넌트 활성/비활성화와 상관없이 데이터가 fetch된 시점부터 계속 흘러간다. (페이지를 머무르고 있든, 페이지를 벗어났든, 컴포넌트가 언마운트 되었든 상관없이 마지막으로 데이터를 가져온 시간으로 계산이 된다)

정리해보기

staleTime
gcTime
언제까지 fresh로 볼 것인가?
inactive 캐시를 언제 삭제할 것인가?
refetch 빈도에 영향을 준다.
이전 데이터를 다시 보여줄 수 있는 기간에 영향을 준다.
길수록 API 요청이 줄어든다.
길수록 메모리에 남는다.