Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 23 of the Intermediate React: Hooks, State & Data Patterns course
ReactJune 26, 20264 min read

Caching Strategies with React Query: Optimize Your API Performance

Master React Query caching to slash network overhead. Learn how to configure staleTime, gcTime, and background revalidation for a faster dashboard.

reactreact queryperformancecachingapifrontendjavascript

Previously in this course, we explored the Asynchronous Data Lifecycle, where we learned to handle loading, error, and success states manually. While that pattern is essential for understanding the basics, it doesn't scale well for complex applications. In this lesson, we shift to react query, a powerful library that abstracts away the manual labor of state synchronization, focusing specifically on how caching impacts performance and API overhead.

Understanding React Query Caching Principles

When you fetch data, you aren't just retrieving a value; you are creating a "snapshot" of the server state. The goal of caching is to determine how long that snapshot remains valid before you need to fetch a fresh one.

React Query manages this through two primary time-based configurations:

  1. staleTime: This determines how long data is considered "fresh." If a component requests data that is still fresh, React Query returns the cached data immediately without making a network request.
  2. gcTime (formerly cacheTime): This defines how long inactive data stays in memory. Once a query becomes inactive (i.e., no components are using it), React Query keeps it in the cache for this duration before garbage collecting it.

Think of staleTime as your performance threshold—it’s how long you are willing to trust the client-side state without verifying it against the server.

Worked Example: Configuring the Dashboard Cache

In our dashboard project, we frequently fetch user analytics. Fetching these on every component mount would be wasteful. Here is how we implement a caching strategy to optimize our API performance:

JAVASCRIPT
import { useQuery } from CE9178">'@tanstack/react-query';

const fetchDashboardStats = async () => {
  const res = await fetch(CE9178">'/api/dashboard-stats');
  return res.json();
};

export const useDashboardStats = () => {
  return useQuery({
    queryKey: [CE9178">'dashboard-stats'],
    queryFn: fetchDashboardStats,
    // Data remains fresh for 5 minutes, preventing redundant fetches
    staleTime: 1000 * 60 * 5, 
    // Data stays in memory for 30 minutes after the component unmounts
    gcTime: 1000 * 60 * 30,
    // Disable automatic background revalidation on window focus
    refetchOnWindowFocus: false,
  });
};

By setting staleTime, we significantly reduce the number of unnecessary network requests. When the user navigates away from the dashboard and returns within five minutes, the data is pulled instantly from the cache.

Background Revalidation

Even when data is "stale," React Query doesn't necessarily show a loading spinner. By default, it performs background revalidation. If a user focuses the browser window or navigates back to a component, React Query will serve the stale data immediately while silently fetching the updated version in the background.

This is a massive UX win. The user sees content instantly, and the UI updates seamlessly if the data has changed. If you need to disable this behavior to save bandwidth, you can use refetchOnWindowFocus: false or refetchOnMount: false.

Hands-on Exercise

Modify your current dashboard data-fetching hook:

  1. Locate your useDashboardStats or similar data-fetching hook.
  2. Add a staleTime of 30 seconds.
  3. Observe the Network tab in your browser developer tools.
  4. Navigate between pages. Notice how the second navigation request is blocked or served from the cache, unlike the Asynchronous Data Lifecycle approach where every mount triggered a fetch.

Common Pitfalls

  • Setting staleTime to 0 (default): This forces a network request on every mount. While it ensures the freshest data, it often creates a "loading flicker" that degrades the user experience.
  • Confusing staleTime and gcTime: Remember, staleTime is about freshness, while gcTime is about memory management. If your gcTime is shorter than your staleTime, your cache will be deleted before it even has a chance to be "fresh." Always ensure gcTime is equal to or greater than staleTime.
  • Over-fetching: Avoid setting staleTime to Infinity for data that changes frequently. If the data is critical (like account balances), you need to balance performance with accuracy.

Recap

Caching is the most effective lever you have for improving perceived performance. By fine-tuning staleTime and gcTime, you minimize redundant API traffic and ensure your dashboard remains snappy. React Query handles the heavy lifting, allowing you to focus on building features rather than managing loading states.

Up next: Mutations and Data Updates — we will learn how to push changes back to the server and keep the UI in sync.

Previous lessonAsynchronous Data LifecycleNext lesson Mutations and Data Updates
Back to Blog

Similar Posts

ReactJune 26, 20263 min read

Protected Routes for Authenticated Views in React

Learn to implement protected routes in your React application. We'll show you how to guard dashboard pages and redirect unauthenticated users securely.

Read more
ReactJune 26, 20263 min read

Introduction to React Router: Building Multi-Page SPAs

Learn how to use React Router to transform your dashboard into a seamless single-page application (SPA) with efficient routing and navigation.

Part of the course

Intermediate React: Hooks, State & Data Patterns

intermediate · Lesson 23 of 48

  1. 1

    Mastering useRef for DOM Access

    4 min
  2. 2

    Persistent Mutable Values with useRef

    4 min
  3. 3

    Memoizing Expensive Calculations with useMemo

    3 min
Read more
ReactJune 25, 20263 min read

Handling Authentication State with React Context API

Learn to manage authentication state in React using the Context API. Build a secure, scalable AuthProvider to track login status and handle user sessions.

Read more
4

Optimizing Function References with useCallback

3 min
  • 5

    Introduction to Custom Hooks

    4 min
  • 6

    Building a useLocalStorage Hook

    4 min
  • 7

    Refactoring Dashboard Settings

    4 min
  • 8

    Complex State with useReducer

    3 min
  • 9

    Managing Object-Based State

    3 min
  • 10

    Introduction to Context API

    3 min
  • 11

    Architecting Global State with Context and Reducer

    3 min
  • 12

    Implementing Theme Context

    4 min
  • 13

    Structuring State for Performance

    3 min
  • 14

    Handling Authentication State

    3 min
  • 15

    Integrating Reducers with Auth State

    3 min
  • 16

    Introduction to React Router

    3 min
  • 17

    Dynamic Routing with URL Parameters

    3 min
  • 18

    Nested Routes and Layouts

    4 min
  • 19

    Protected Routes for Authenticated Views

    3 min
  • 20

    Programmatic Navigation

    3 min
  • 21

    Building the Dashboard Navigation Structure

    3 min
  • 22

    Asynchronous Data Lifecycle

    3 min
  • 23

    Caching Strategies with React Query

    4 min
  • 24

    Mutations and Data Updates

    4 min
  • 25

    Synchronizing Client and Server State

    3 min
  • 26

    Integrating Live Data into the Dashboard

    3 min
  • 27

    Error Handling and Loading UI

    3 min
  • 28

    Controlled vs Uncontrolled Components

    Coming soon
  • 29

    Real-time Form Validation

    Coming soon
  • 30

    Schema-based Validation with Zod

    Coming soon
  • 31

    Handling Multi-step Forms

    Coming soon
  • 32

    Optimizing Form Submissions

    Coming soon
  • 33

    Performance Profiling with React DevTools

    Coming soon
  • 34

    Refactoring for Scalability

    Coming soon
  • 35

    Finalizing Dashboard Data Flow

    Coming soon
  • 36

    Deploying the Application

    Coming soon
  • 37

    Advanced Hook Composition

    Coming soon
  • 38

    Implementing Middleware for State

    Coming soon
  • 39

    Advanced Context Patterns

    Coming soon
  • 40

    Router Loaders and Data Prefetching

    Coming soon
  • 41

    Complex Route Guards

    Coming soon
  • 42

    Handling Large Datasets in UI

    Coming soon
  • 43

    Testing Hooks and Components

    Coming soon
  • 44

    Managing Global Modals

    Coming soon
  • 45

    Implementing Keyboard Shortcuts

    Coming soon
  • 46

    Optimizing Asset Loading

    Coming soon
  • 47

    Internationalization Basics

    Coming soon
  • 48

    Managing WebSocket Connections

    Coming soon
  • View full course