staleTime과 gcTime의 차이점

react-query에서 캐시는 매우 중요한 요소이다. 실무에서 캐시때문에 장애를 내본 경험이 있어서 자세히 정리하려고 한다.

staleTime

staleTime은 불러온 데이터가 fresh한 시간을 나타낸다. 기본값은 0으로, react-query팀에서는 기본적으로 불러온 데이터는 fresh하지 않다고 간주한다.

0으로 사용한다면 해당 hook을 사용하는 컴포넌트가 mount될때 마다 data-fetching을 시도할 것이다.

gcTime

v4까지 cacheTime으로 불리어왔던 값인데 v5로 업데이트되면서 gcTime으로 이름이 변경되었다. 직관적으로 gcTime은 쿼리가 캐시에서 삭제될 때까지의 시간을 나타낸다. 쿼리의 캐시가 사용되지 않거나 비활성 상태가 되면 해당 캐시 데이터는 이 기간이 지나면 가비지로 수집된다.

최대 24일 까지 설정할 수 있으며 Infinity로 설정하면 가비지 수집이 비활성화된다.

staleTime과 gcTime의 연관성

staleTime과 gcTime은 전혀 관련이 없는 완전히 다른 두 개의 시간이다. 서로 다른 용도로 사용되며, 각각이 다른 시간보다 작거나 클 수 있지만 상관없다.

staleTime: 쿼리가 새 쿼리에서 오래된 쿼리(stale한 상태)로 전환될 때까지의 기간이다. 쿼리가 새 상태인 한, 데이터는 항상 캐시에서만 읽혀지며 네트워크 요청은 발생하지 않는다. 쿼리가 stale한 상태인 경우(기본값은 즉시) 캐시에서 데이터를 계속 가져오지만 특정 조건에서는 백그라운드 리페치가 발생할 수 있다.

여기서 주목해야할 점은 staleTime이 경과하더라도 즉시 요청이 발생하지 않는다는 것이다. staleTime은 단지 캐시에 있는 데이터가 더 이상 최신이 아니므로 백트라운드에서 새로고침 될 수 있음을 알려줄 뿐이다. 하지만 백그라운드에서 새로 고침이 일어나려면 "트리거"가 필요하다.

gcTime(cacheTime): 비활성 쿼리가 캐시에서 제거될 때까지의 시간이다. 기본값은 5분이다. 쿼리는 등록된 옵저버가 없는 즉시, 해당 쿼리를 사용하는 모든 컴포넌트가 마운트 해체되면 비활성 상태로 전환된다.

쿼리를 사용하는 한 gcTime은 아무 일도 하지 않는다. 웹 페이지를 열고 해당 페이지에서 영원히 작업할 수 있다. React Query는 해당 데이터를 제거하지 않으므로 화면이 로딩 상태로 전환될 수 있다. 이는 좋지 않다. 캐시타임은 더 이상 사용되지 않는 데이터를 제거하는 가비지 수집에 관한 것입니다. 이것이 gcTime으로 변경된 이유이다.

staleTime보다 gcTime이 크다면

문제가 되는 것은 아니지만 다음과 같은 의미이다.

캐시된 데이터가 있는 경우 데이터를 다시 불러오지 말고 더 이상 사용되지 않는 즉시 캐시에서 데이터를 제거해라.

보통 gcTime은 건드리지 않고 staleTime으로 조정하는것을 메인테이너는 권장하고 있는 듯하다.

참고: https://stackoverflow.com/questions/75211088/if-staletime-is-bigger-than-cachetime-in-react-query-what-happen