Data Fetching: Fetching, Caching, and Revalidating (2024)

Data fetching is a core part of any application. This page goes through how you can fetch, cache, and revalidate data in React and Next.js.

There are four ways you can fetch data:

  1. On the server, with fetch
  2. On the server, with third-party libraries
  3. On the client, via a Route Handler
  4. On the client, with third-party libraries.

Fetching Data on the Server with fetch

Next.js extends the native fetch Web API to allow you to configure the caching and revalidating behavior for each fetch request on the server. React extends fetch to automatically memoize fetch requests while rendering a React component tree.

You can use fetch with async/await in Server Components, in Route Handlers, and in Server Actions.

For example:

app/page.tsx

async function getData() { const res = await fetch('https://api.example.com/...') // The return value is *not* serialized // You can return Date, Map, Set, etc.  if (!res.ok) { // This will activate the closest `error.js` Error Boundary throw new Error('Failed to fetch data') }  return res.json()} export default async function Page() { const data = await getData()  return <main></main>}

Good to know:

  • Next.js provides helpful functions you may need when fetching data in Server Components such as cookies and headers. These will cause the route to be dynamically rendered as they rely on request time information.
  • In Route handlers, fetch requests are not memoized as Route Handlers are not part of the React component tree.
  • To use async/await in a Server Component with TypeScript, you'll need to use TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.

Caching Data

Caching stores data so it doesn't need to be re-fetched from your data source on every request.

By default, Next.js automatically caches the returned values of fetch in the Data Cache on the server. This means that the data can be fetched at build time or request time, cached, and reused on each data request.

// 'force-cache' is the default, and can be omittedfetch('https://...', { cache: 'force-cache' })

fetch requests that use the POST method are also automatically cached. Unless it's inside a Route Handler that uses the POST method, then it will not be cached.

What is the Data Cache?

The Data Cache is a persistent HTTP cache. Depending on your platform, the cache can scale automatically and be shared across multiple regions.

Learn more about the Data Cache.

Revalidating Data

Revalidation is the process of purging the Data Cache and re-fetching the latest data. This is useful when your data changes and you want to ensure you show the latest information.

Cached data can be revalidated in two ways:

  • Time-based revalidation: Automatically revalidate data after a certain amount of time has passed. This is useful for data that changes infrequently and freshness is not as critical.
  • On-demand revalidation: Manually revalidate data based on an event (e.g. form submission). On-demand revalidation can use a tag-based or path-based approach to revalidate groups of data at once. This is useful when you want to ensure the latest data is shown as soon as possible (e.g. when content from your headless CMS is updated).

Time-based Revalidation

To revalidate data at a timed interval, you can use the next.revalidate option of fetch to set the cache lifetime of a resource (in seconds).

fetch('https://...', { next: { revalidate: 3600 } })

Alternatively, to revalidate all fetch requests in a route segment, you can use the Segment Config Options.

layout.js / page.js

export const revalidate = 3600 // revalidate at most every hour

If you have multiple fetch requests in a statically rendered route, and each has a different revalidation frequency. The lowest time will be used for all requests. For dynamically rendered routes, each fetch request will be revalidated independently.

Learn more about time-based revalidation.

On-demand Revalidation

Data can be revalidated on-demand by path (revalidatePath) or by cache tag (revalidateTag) inside a Route Handler or a Server Action.

Next.js has a cache tagging system for invalidating fetch requests across routes.

  1. When using fetch, you have the option to tag cache entries with one or more tags.
  2. Then, you can call revalidateTag to revalidate all entries associated with that tag.

For example, the following fetch request adds the cache tag collection:

app/page.tsx

export default async function Page() { const res = await fetch('https://...', { next: { tags: ['collection'] } }) const data = await res.json() // ...}

If using a Route Handler, you should create a secret token only known by your Next.js app. This secret will be used to prevent unauthorized revalidation attempts. For example, you can access the route (either manually or with a webhook) with the following URL structure:

URL

https://<your-site.com>/api/revalidate?tag=collection&secret=<token>

app/api/revalidate/route.ts

import { NextRequest, NextResponse } from 'next/server'import { revalidateTag } from 'next/cache' // e.g a webhook to `your-website.com/api/revalidate?tag=collection&secret=<token>`export async function POST(request: NextRequest) { const secret = request.nextUrl.searchParams.get('secret') const tag = request.nextUrl.searchParams.get('tag')  if (secret !== process.env.MY_SECRET_TOKEN) { return NextResponse.json({ message: 'Invalid secret' }, { status: 401 }) }  if (!tag) { return NextResponse.json({ message: 'Missing tag param' }, { status: 400 }) }  revalidateTag(tag)  return NextResponse.json({ revalidated: true, now: Date.now() })}

Alternatively, you can use revalidatePath to revalidate all data associated with a path.

app/api/revalidate/route.ts

import { NextRequest, NextResponse } from 'next/server'import { revalidatePath } from 'next/cache' export async function POST(request: NextRequest) { const path = request.nextUrl.searchParams.get('path')  if (!path) { return NextResponse.json({ message: 'Missing path param' }, { status: 400 }) }  revalidatePath(path)  return NextResponse.json({ revalidated: true, now: Date.now() })}

Learn more about on-demand revalidation.

Error handling and revalidation

If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data.

Opting out of Data Caching

fetch requests are not cached if:

  • The cache: 'no-store is added to fetch requests.
  • The revalidate: 0 option is added to individual fetch requests.
  • The fetch request is inside a Router Handler that uses the POST method.
  • The fetch request comes after the usage of headers or cookies.
  • The const dynamic = 'force-dynamic' route segment option is used.
  • The fetchCache route segment option is configured to skip cache by default.
  • The fetch request uses Authorization or Cookie headers and there's an uncached request above it in the component tree.

Individual fetch Requests

To opt out of caching for individual fetch requests, you can set the cache option in fetch to 'no-store'. This will fetch data dynamically, on every request.

layout.js / page.js

fetch('https://...', { cache: 'no-store' })

View all the available cache options in the fetch API reference.

Multiple fetch Requests

If you have multiple fetch requests in a route segment (e.g. a Layout or Page), you can configure the caching behavior of all data requests in the segment using the Segment Config Options.

For example, using const dynamic = 'force-dynamic' will cause all data to be fetched at request time, and the segment to be rendered dynamically.

layout.js / page.js

// Addexport const dynamic = 'force-dynamic'

There's an extensive list of Segment Config options, giving you fine-grained control of static and dynamic behavior of a route segment. See the API reference for more.

Fetching data on the Server with third-party libraries

In cases where you're using a third-party library that doesn't support or expose fetch (for example, a database, CMS, or ORM client), you can configure the caching and revalidating behavior of those requests using the Route Segment Config Option and React's cache function.

Whether the data is cached or not will depend on whether the route segment is statically or dynamically rendered. If the segment is static (default), the output of the request will be cached and revalidated as part of the route segment. If the segment is dynamic, the output of the request will not be cached and will be re-fetched on every request when the segment is rendered.

Good to know:

Next.js is working on an API, unstable_cache, for configuring the caching and revalidating behavior of individual third-party requests.

Example

In the example below:

  • The revalidate option is set to 3600, meaning the data will be cached and revalidated at most every hour.
  • The React cache function is used to memoize data requests.

utils/get-item.ts

import { cache } from 'react' export const revalidate = 3600 // revalidate the data at most every hour export const getItem = cache(async (id: string) => { const item = await db.item.findUnique({ id }) return item})

Although the getItem function is called twice, only one query will be made to the database.

app/item/layout.tsx

import { getItem } from '@/utils/get-item' export default async function Layout({ params: { id },}: { params: { id: string }}) { const item = await getItem(id) // ...}

app/item/[id]/page.tsx

import { getItem } from '@/utils/get-item' export default async function Page({ params: { id },}: { params: { id: string }}) { const item = await getItem(id) // ...}

Fetching Data on the Client with Route Handlers

If you need to fetch data in a client component, you can call a Route Handler from the client. Route Handlers execute on the server and return the data to the client. This is useful when you don't want to expose sensitive information to the client, such as API tokens.

See the Route Handler documentation for examples.

Server Components and Route Handlers

Since Server Components render on the server, you don't need to call a Route Handler from a Server Component to fetch data. Instead, you can fetch the data directly inside the Server Component.

Fetching Data on the Client with third-party libraries

You can also fetch data on the client using a third-party library such as SWR or React Query. These libraries provide their own APIs for memoizing requests, caching, revalidating, and mutating data.

Future APIs:

use is a React function that accepts and handles a promise returned by a function. Wrapping fetch in use is currently not recommended in Client Components and may trigger multiple re-renders. Learn more about use in the React RFC.

Data Fetching: Fetching, Caching, and Revalidating (2024)

FAQs

What is the data fetching process? ›

Initially, the user provides the credential of database to connect with it. The server handles the further process by executing various queries to fetch the spatio- temporal information from the database. This mode handles both vector and raster data. The vector objects like line, circle, polyline etc .

What are the best practices for caching data? ›

Best Practices for Caching

Define a cache eviction policy to ensure that the cache does not consume too much memory. Use a consistent cache key format to ensure that data can be retrieved from the cache correctly. Implement cache invalidation to ensure that cached data is updated when the underlying data changes.

What is the two tier caching strategy? ›

In the two-layer caching model, ground stations and satellite networks collaboratively cache to achieve global planning of cache contents, rationalize the utilization of cache resources, and reduce the propagation delay of remote sensing data.

Which of the following is a best practice for optimizing performance in a distributed caching solution? ›

A Timer background Action pushes data into the distributed cache on a regular schedule. Any consumer application pulls the same data from the cache without being responsible for updating the data. This approach works great with high latency data sources or operations that don't always require the latest data.

What steps will you take to fetch data from the database? ›

Fetch data from a database
  1. Start by creating a new app.
  2. Add a Screen to your app. ...
  3. Add data sources to your app by referencing some Entities in the Manage Dependencies window (Ctrl+Q). ...
  4. Publish the app by clicking the 1-Click Publish button. ...
  5. It's time to load some data to the Screen.
Aug 2, 2023

What is the difference between fetching and loading? ›

"Load" refers to taking the value and assigning it to a register or variable, whereas "fetch" refers to taking the value and using it directly in an operation.

What are caching techniques? ›

How does Caching work? The data in a cache is generally stored in fast access hardware such as RAM (Random-access memory) and may also be used in correlation with a software component. A cache's primary purpose is to increase data retrieval performance by reducing the need to access the underlying slower storage layer.

What is an example of when you would use caching? ›

A common example of caching is a web browser that stores page content on a local disk for a designated period of time. When the user first visits the website, the content is downloaded from the web server and saved to a local directory.

What is the biggest issue with caching? ›

Cache Breakdown (Thundering herd problem)

A cache breakdown happens when a cache key expires, and multiple requests access the database concurrently looking for the same key. A hot cache key expires. Multiple concurrent requests come in searching for the same key.

What is the best pattern of caching? ›

Read-aside caching (commonly called "lazy loading") is the most common caching design pattern. With this strategy, your application will first try to request your needed data from a cache. If the data is there, it will return to the caller. If not, it will request the data from the primary data source.

What are the three types of caching used in net? ›

ASP.NET has the following main types of caching:
  • Page caching.
  • Fragment caching.
  • Data caching.

How many types of caching techniques are there? ›

There are four major caching types used in web development. We will learn about each of these caches in the next set of cards. Web Caching helps reduce overall network traffic and latency. Browser caching helps individual users to quickly navigate pages they have recently visited.

What type of cache is the simplest to implement? ›

Direct mapping is the simplest to implement. In a direct mapped cache, the cache block is available before determining whether it is a hit or a miss, as it is possible to assume a hit and continue and recover later if it is a miss.

What are two approaches that can be used for cache invalidation? ›

Cache invalidation is the process of removing or updating outdated or stale data from the cache. There are two main approaches to cache invalidation: push and pull.

How does server caching improve performance? ›

Caching is a technique that stores copies of frequently used or static resources, such as images, scripts, stylesheets, or fonts, on the server or the browser. This way, when a user visits your website, they don't have to download the same resources every time, which saves bandwidth and improves loading speed.

What is fetch in SQL processing? ›

The FETCH statement retrieves rows of data from the result set of a multiple-row query—one row at a time, several rows at a time, or all rows at once—and stores the data in variables, records, or collections.

What is the response of fetch process? ›

Fetch API Syntax

First, you send a request to the desired URL using the fetch() method. Next, you handle the response with the . then() method. In this case, we're not doing anything with the code yet, but you could use this same code to parse HTML documents, send data over POST requests, and more.

How data is fetched from server? ›

The main API here is the Fetch API. This enables JavaScript running in a page to make an HTTP request to a server to retrieve specific resources. When the server provides them, the JavaScript can use the data to update the page, typically by using DOM manipulation APIs.

What does it mean to fetch data from API? ›

The Fetch API is a modern interface that allows you to make HTTP requests to servers from web browsers. If you have worked with XMLHttpRequest ( XHR ) object, the Fetch API can perform all the tasks as the XHR object does. In addition, the Fetch API is much simpler and cleaner.

Top Articles
Latest Posts
Article information

Author: Catherine Tremblay

Last Updated:

Views: 5713

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Catherine Tremblay

Birthday: 1999-09-23

Address: Suite 461 73643 Sherril Loaf, Dickinsonland, AZ 47941-2379

Phone: +2678139151039

Job: International Administration Supervisor

Hobby: Dowsing, Snowboarding, Rowing, Beekeeping, Calligraphy, Shooting, Air sports

Introduction: My name is Catherine Tremblay, I am a precious, perfect, tasty, enthusiastic, inexpensive, vast, kind person who loves writing and wants to share my knowledge and understanding with you.