Next.js has its own caching system that handles caching at the route and fetch level. This page focuses on React's built-in Server Component level caching.

React Server Components can use the cache function to memoize expensive computations or data fetching operations. This is similar to useMemo on the client side, but it works on the server and persists between components that use the same cached function.

The cache function returns a cached result instead of re-executing the computation. This mechanism is particularly useful for:

  • Server Components that appear many times in the tree
  • Expensive database queries
  • Complex calculations
  • API calls that return the same data for the same parameters

Note that the cache persists when rendering components during the same server request, but it is invalidated upon a new server request.

RSCs without Cache
Notice that each time the component is rendered, the data is fetched again.
server
node.js
Nathaniel Nolan's avatar

Nathaniel Nolan

Human Metrics Orchestrator

Max Beer's avatar

Max Beer

Internal Usability Producer

Leroy Lubowitz's avatar

Leroy Lubowitz

Investor Optimization Agent

server
node.js
Pablo Satterfield's avatar

Pablo Satterfield

Chief Paradigm Analyst

Alexander Dickinson-Kiehn's avatar

Alexander Dickinson-Kiehn

Legacy Brand Architect

Bennie Lubowitz's avatar

Bennie Lubowitz

Global Optimization Manager

RSCs with Cache
Notice that each time the component is rendered, the data stays the same (from a cache).
server
node.js
Dr. Shannon Kunde's avatar

Dr. Shannon Kunde

Direct Configuration Technician

Pam Tremblay's avatar

Pam Tremblay

International Division Associate

Meredith Abshire DDS's avatar

Meredith Abshire DDS

Investor Intranet Planner

server
node.js
Dr. Shannon Kunde's avatar

Dr. Shannon Kunde

Direct Configuration Technician

Pam Tremblay's avatar

Pam Tremblay

International Division Associate

Meredith Abshire DDS's avatar

Meredith Abshire DDS

Investor Intranet Planner

RSC Without Cache
/*
This is wasteful as the database will be
called each time the component is rendered.
*/

async function DemoProfile() {
const user = await db.user.query(userId);
return <Profile user={user} />;
}
RSC With Cache
import { cache } from 'react';

// userId serves as a cache key
const getUser = cache(async (userId) => {
return await db.user.query(userId);
});

async function DemoProfile() {
const user = await getUser('demo-id');
return <Profile user={user} />;
}
Next, let's see how much of an effect this can have when chaining multiple Suspense components.