Skip to main content

Why cache request results?

What does "caching request results" mean?

Caching is the temporary storage of request results, so that a repeated request for the same data does not trigger a new HTTP request, but instead uses the data already obtained from memory.

Example:

javascript
// Without cache - a new request every time await fetch('/api/products'); // With cache - use the stored result if it's still valid cache.get('/api/products') ?? fetch('/api/products');

Why cache at all?

1. Speed (a faster UI)

Every request to the server:

  • takes time (even 100-300 ms is already noticeable);
  • causes extra renders, "flickering" loaders;
  • can be expensive (a database, a third-party API).

When you cache a result, repeated requests for the same data:

  • arrive instantly from memory (RAM);
  • don't show a loader;
  • create the feeling of a "reactive" interface, like in native apps.

The user switches instantly between pages and tabs without reloading.


2. Reduced server load

Without a cache, 100 users opening /products make 100 requests. With a cache, there's one request, and the rest get the data locally.

The result:

  • less traffic,
  • lower latency,
  • cheaper infrastructure,
  • the API lasts longer without overload.

3. Fewer "loading" states

When you navigate between pages and come back:

  • without a cache → "Loading..." again,
  • with a cache → the data already exists, the UI renders instantly.

This sharply improves UX (the perceived "speed" of the interface).


4. Offline and "stale-while-revalidate" modes

A cache lets you:

  • show old data offline (for example, when the network is lost),
  • update data in the background without blocking the user.

This pattern is called Stale-While-Revalidate (SWR):

  1. Show the stale (cached) data instantly.
  2. Send a request for fresh data in the background.
  3. When the new data arrives, update the UI.

5. Avoiding "duplicate requests"

If component A and component B make the same request at the same time:

javascript
fetch('/api/user') fetch('/api/user')

without a cache, the server gets two requests. With a cache (or a library like React Query), there's only one request, and both components get the same result from the cache.

This is called deduplication.


6. Optimizing UX during navigation

If you:

  • opened the list page (/products),
  • then went to a product card (/products/42),
  • and then went back,

without a cache, the list page loads from scratch again. With a cache, the list is already in memory, and React shows it instantly.


How to cache in React in practice

1. Manually via Map or localStorage

javascript
const cache = new Map(); async function fetchWithCache(url) { if (cache.has(url)) return cache.get(url); const res = await fetch(url); const data = await res.json(); cache.set(url, data); return data; }

Pros: simple, it works. Cons: no invalidation, stale data, duplicated logic.


2. Via React Query (TanStack Query)

The modern standard for caching data in React applications:

javascript
import { useQuery } from '@tanstack/react-query'; function User({ id }) { const { data, isLoading } = useQuery({ queryKey: ['user', id], queryFn: () => fetch(`/api/users/${id}`).then(r => r.json()), staleTime: 5 * 60 * 1000, // 5-minute cache }); if (isLoading) return <p>Loading...</p>; return <p>{data.name}</p>; }

React Query:

  • caches data in memory (QueryClient);
  • performs deduplication;
  • manages stale and refetch;
  • automatically refetches on tab focus;
  • lets you set staleTime, cacheTime, refetchOnMount, and more.

3. Via SWR (by Vercel)

A lightweight library built on the Stale-While-Revalidate concept:

javascript
import useSWR from 'swr'; const fetcher = url => fetch(url).then(r => r.json()); function User({ id }) { const { data, error, isLoading } = useSWR(`/api/users/${id}`, fetcher); if (isLoading) return <p>Loading...</p>; if (error) return <p>Error...</p>; return <p>{data.name}</p>; }

SWR automatically:

  • caches data by key (/api/users/${id});
  • refreshes background data when you return to the page;
  • lets you use mutate() to manually update the cache.

4. Persisted cache (keeping the cache between sessions)

React Query, SWR, and Apollo Client support a persisted cache:

  • it saves the cache to localStorage or IndexedDB;
  • on app restart, the data is available instantly;
  • an API request runs in the background to sync.

SUMMARY

ReasonWhy cache
SpeedInstant display of data without loaders
UXA stable interface when navigating and coming back
Network optimizationFewer requests → lower latency and load
DeduplicationOne request, many consumers
The SWR approachShows the old data → updates with the new
OfflineYou can work without a network
ResilienceEven on a network error, UX doesn't break

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.