React Query를 사용할 때 두 설정값, staleTime과 gcTime은 매번 헷갈렸습니다. 단순히 "신선한 시간"과 "캐시 삭제 시간"으로만 알고 있었기 때문에, 실제로 특정 시간이 지났을 때 어떻게 동작하는지 시나리오별로 정리해 볼 필요가 있었습니다!
staleTime은 데이터가 신선(Fresh)하다고 간주하는 시간입니다. 이 시간이 지나서 데이터가 상한(Stale) 상태가 된다면 API 요청을 통해 새로운 데이터를 가지고 오겠죠?
gcTime(구 cacheTime)은 데이터가 화면에서 사라져서 사용되지 않을 때(inactive), 메모리에 얼마나 유지될지, 그 시간을 의미합니다. 이 시간이 지나면 가비지 컬렉터(GC)가 메모리에 저장된 데이터를 삭제합니다.
staleTime: 5분, gcTime: 15분 으로 설정했다고 가정해 봅시다.
staleTime이 지나기 전인 0분에서 5분 사이에는 데이터가 아주 신선한 상태입니다. 또한 gcTime도 지나지 않았기 때문에 캐시된 데이터도 메모리에 저장되어 있죠. 따라서, 다시 조회했을 때 캐시된 데이터를 즉시 보여줍니다.
5분이 지나면 데이터는 상한 상태가 됩니다. 하지만 아직 15분(gcTime)이 지나지 않았다면 메모리에 캐시 데이터는 살아있죠. 이때 사용자가 다시 해당 데이터를 요청하면, Tanstack Query는 일단 낡은 캐시 데이터라도 화면에 보여줍니다. 그와 동시에 뒤에서는 조용히 새 데이터를 가져와(Revalidation) 화면을 최신 상태로 업데이트해 줍니다. 덕분에 사용자는 끊김이 없는 경험을 할 수 있어요.
만약 15분이 지나 staleTime도 gcTime도 지났을 때는 어떻게 될까요? 캐시도 없고, 데이터도 상했다고 판단하므로 로딩 스피너를 보여주며 데이터를 새로 가져올 것입니다.
결론부터 말하자면 이 설정에서는 staleTime이 아무런 힘을 쓰지 못합니다. 왜 그런지 조금만 생각해 보면 답이 나오는데요, staleTime: 15분, gcTime: 5분 으로 설정했다고 가정해 봅시다.
만약 6분이 지났다면, 데이터가 신선함에도 불구하고 캐시가 메모리에서 삭제되었기 때문에 새로 API 요청을 해야 합니다. 유통기한이 지나지 않은 우유를 쓰레기통에 버려서 또 사야 하는 것과 같은 이상한 상황이죠 🤷
이런 이상한 상황이 발생하지 않으려면, gcTime을 staleTime보다 작게 설정하지 않도록 주의해야 합니다!
Tanstack Query의 기본값은 staleTime: 0, gcTime: 5 * 60 * 1000(5분) 입니다. 기본적으로 매번 백그라운드에서 데이터를 새로 가져오고, 5분 내로 페이지를 나갔다가 들어올 때만 캐시를 활용하도록 설계되어 있습니다.
각 데이터의 성격에 맞춰 이 밸런스를 잘 조절하여 API 요청을 최소화하는 므찐 개발자가 됩시다~