React 19 introduces cache() for request-level memoization in Server Components. It caches the result of an expensive function call (like a database query) so that multiple calls with the same arguments within a single request return the cached result.
How it works:
Complete code example:
1import { cache } from "react";23// Cache an expensive database call4const getUser = cache(async (id: string) => {5 console.log(`Fetching user ${id}`); // Only logs once per request6 const response = await fetch(`/api/users/${id}`);7 return response.json();8});910// Cache another expensive call11const getPosts = cache(async (userId: string) => {12 const response = await fetch(`/api/users/${userId}/posts`);13 return response.json();14});1516// Server Component17async function UserPage({ params }: { params: { id: string } }) {18 // Both calls use the same cache — only one fetch happens19 const user = await getUser(params.id);20 const profile = await getUser(params.id); // cached!2122 // This is a different function, so it runs separately23 const posts = await getPosts(params.id);2425 return (26 <div>27 <h1>{user.name}</h1>28 <p>{user.email}</p>29 <h2>Posts ({posts.length})</h2>30 <ul>31 {posts.map(post => (32 <li key={post.id}>{post.title}</li>33 ))}34 </ul>35 </div>36 );37}
Benefits:
getUser(123) share the cachecache()Comparison with other approaches:
| Approach | Scope | Use Case |
|---------|-------|----------|
| cache() | Per-request (server) | Deduplicate DB calls in server components |
| useMemo | Per-render (client) | Cache expensive computations in client components |
| useEffect + state | Per-render (client) | Fetch data after render (causes waterfalls) |
| TanStack Query | Global (client) | Cache server data with stale-while-revalidate |
Important: cache() only works in server components. For client-side caching, use React Query, SWR, or useMemo.