# React Query Caching Strategies for Roadmap Content in the Developer Roadmap Project

> Discover efficient React Query caching strategies for roadmap content in the developer roadmap project. Learn how to balance static data caching with dynamic progress updates.

- Repository: [Kamran Ahmed/developer-roadmap](https://github.com/kamranahmedse/developer-roadmap)
- Tags: deep-dive
- Published: 2026-02-24

---

**The kamranahmedse/developer-roadmap repository employs a tiered React Query caching architecture that balances aggressive caching for static roadmap structures with rapid invalidation for user-specific progress data.**

The frontend of the popular [developer-roadmap](https://github.com/kamranahmedse/developer-roadmap) project relies on TanStack Query (formerly React Query) to manage all server state. By configuring `staleTime` and `cacheTime` parameters at both global and query-specific levels, the application eliminates unnecessary network requests while ensuring that personalized progress markers remain responsive to user interactions.

## Global QueryClient Configuration

The foundation of the caching strategy resides in [`src/stores/query-client.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/stores/query-client.ts), where the global `QueryClient` instance defines conservative defaults applicable to all queries. This configuration establishes a baseline that prioritizes performance over real-time synchronization for content that rarely changes during a user session.

```typescript
import { QueryCache, QueryClient } from '@tanstack/react-query';

export const queryClient = new QueryClient({
  queryCache: new QueryCache(),
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000,          // 5 minutes
      cacheTime: 30 * 60 * 1000,         // 30 minutes
      refetchOnWindowFocus: false,
      refetchOnReconnect: false,
      retry: 1,
    },
  },
});

```

These global settings ensure that roadmap data remains fresh in memory for five minutes before background refetching occurs, while inactive queries persist in the cache for thirty minutes after component unmounting. The explicit disabling of `refetchOnWindowFocus` prevents jarring UI updates when users return to the tab, as roadmap JSON structures remain static during typical browsing sessions.

## Tiered Caching for Different Data Volatility

Beyond global defaults, the application implements query-specific caching strategies in `src/queries/` that match the update frequency of each data type. This layered approach prevents over-fetching of immutable content while maintaining responsiveness for mutable user state.

### Static Roadmap Structures

For the hierarchical roadmap tree and list data defined in [`src/queries/roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/roadmap.ts) and [`src/queries/roadmap-tree.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/roadmap-tree.ts), the configuration extends cache lifetimes significantly. Because these structures only update when maintainers publish new versions, they utilize extended `staleTime` and `cacheTime` values:

```typescript
import { queryOptions } from '@tanstack/react-query';
import { fetchRoadmapList } from '@/services/api';

export const roadmapListQuery = () =>
  queryOptions({
    queryKey: ['roadmap-list'],
    queryFn: fetchRoadmapList,
    staleTime: 10 * 60 * 1000,   // 10 minutes
    cacheTime: 60 * 60 * 1000,   // 60 minutes
  });

```

The sixty-minute `cacheTime` ensures that returning users experience instant page loads without network overhead, as the roadmap topology remains available in memory long after navigation.

### User-Specific Progress Tracking

Conversely, personal progress data tracked in [`src/queries/resource-progress.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/resource-progress.ts) and [`src/queries/project.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/project.ts) demands near-real-time consistency. When users mark topics as completed, the UI must reflect these changes immediately upon revisiting the page:

```typescript
import { queryOptions } from '@tanstack/react-query';
import { fetchUserProgress } from '@/services/api';

export const userProgressQuery = (resourceId: string) =>
  queryOptions({
    queryKey: ['resource-progress', resourceId],
    queryFn: () => fetchUserProgress(resourceId),
    staleTime: 30 * 1000,   // 30 seconds
    cacheTime: 5 * 60 * 1000,
  });

```

The thirty-second `staleTime` strikes a balance between freshness and performance, allowing brief in-memory reuse while ensuring that progress synchronization occurs within a reasonable timeframe.

### Infinite Scroll Chat History

For paginated chat interfaces implemented via [`src/queries/chat-history.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/chat-history.ts), the application leverages `infiniteQueryOptions` to cache each page of results independently. Each page retains its own `staleTime` and `cacheTime` boundaries, allowing recent conversation history to remain accessible while older pages undergo garbage collection after the cache timeout expires.

## Proactive Cache Warming with Prefetching

The caching strategy extends beyond passive retention through aggressive prefetching. When users hover over roadmap thumbnails or initiate navigation events, the application warms the cache using `queryClient.prefetchQuery`:

```typescript
import { queryClient } from '@/stores/query-client';
import { fetchRoadmapTree } from '@/services/api';

async function prefetchRoadmapTree(slug: string) {
  await queryClient.prefetchQuery({
    queryKey: ['roadmap-tree', slug],
    queryFn: () => fetchRoadmapTree(slug),
    staleTime: 10 * 60 * 1000,
  });
}

```

This pattern ensures that by the time the user clicks through to a detailed roadmap view, the JSON tree structure already resides in memory, producing instantaneous page transitions without loading spinners.

## Summary

- **Global defaults** in [`src/stores/query-client.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/stores/query-client.ts) establish a five-minute `staleTime` and thirty-minute `cacheTime` for all queries, with background refetching disabled to prevent UI disruption.
- **Static content queries** for roadmap trees utilize aggressive sixty-minute caching to accommodate the infrequent update cycle of educational content.
- **Progress tracking queries** implement thirty-second `staleTime` values to balance performance with the need for real-time completion status synchronization.
- **Prefetching strategies** eliminate perceived latency by hydrating the cache during hover states before navigation completes.

## Frequently Asked Questions

### What is the default staleTime for React Query in developer-roadmap?

The global `QueryClient` configuration defined in [`src/stores/query-client.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/stores/query-client.ts) sets a default `staleTime` of five minutes (300,000 milliseconds) for all queries. This default applies unless overridden by specific query configurations in the `src/queries/` directory.

### How does the application handle caching for user progress data?

User progress queries in [`src/queries/resource-progress.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/resource-progress.ts) override global defaults with a `staleTime` of thirty seconds and a `cacheTime` of five minutes. This ensures that completion markers reflect recent user actions while still benefiting from short-term memory caching during active sessions.

### Why does developer-roadmap disable refetchOnWindowFocus?

The application explicitly sets `refetchOnWindowFocus: false` in the global client configuration because roadmap content constitutes static JSON files that do not change during a user's browsing session. Enabling automatic refetching would generate unnecessary network requests without improving data accuracy.

### How does prefetching improve navigation performance?

The application implements `queryClient.prefetchQuery` calls when users hover over roadmap links, fetching and caching the destination data before the navigation event occurs. This cache warming eliminates loading states and ensures that roadmap trees render instantly upon route transitions.