> ## Content Index
> Fetch the complete content index at: https://madewithlove.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Caching routes, components and functions with "use cache" in Next.js 15 (canary)
- URL: https://madewithlove.com/blog/caching-routes-components-and-functions-with-use-cache-in-next-js-15-canary/
- Published: 2024-10-28T08:59:53.000Z
- Updated: 2025-02-25T08:15:33.000Z
- Description: "use cache" is an experimental Next.js 15 Canary feature and may change. In this tutorial, we explore "use cache" for caching, covering fetching and inserting comments with Drizzle to reduce database calls and improve performance while maintaining control.
- Author: Geoffrey Dhuyvetters
- Tags: Engineering, Code quality, Tutorials, JavaScript, React, Frontend

💡

***Warning** *: "use cache" is an experimental feature in the Next.js Canary release channel and may change in the future. Use it with caution.*

In this article, we build on previous articles, where we manipulated data with actions and fetched data with server components:

- [Instant feedback using the useOptimistic hook in React](https://madewithlove.com/blog/instant-feedback-using-the-useoptimistic-hook-in-react/)
- [Passing server data to client components in React](https://madewithlove.com/blog/crossing-boundaries-passing-server-data-to-client-components-in-react/)
- [Handling data mutations in client components](https://madewithlove.com/blog/crossing-boundaries-handling-data-mutations-in-client-components/)

Now, we’ll introduce caching with the experimental **"use cache"** directive in Next.js, which can be applied across **routes**, specific **components**, and **functions**. 

In Next.js 15, **caching is disabled by default**, meaning that data isn’t cached between requests or navigations without explicit instructions. This default setup grants developers full control, enabling them to tailor caching solutions to their applications' unique needs.

## Enable dynamicIO

To enable dynamicIO (and support for the directive), configure your next.config.ts file as shown below:

```Javascript
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    dynamicIO: true,
  },
};

export default nextConfig;
```

## Setting Up Caching

We have a Drizzle setup with a comments schema defined elsewhere. The focus of this article is on two key operations: fetching comments and inserting comments. We'll be applying caching to improve performance and minimise redundant database calls.

### Method 1: Fetching Comments and Caching

Instead of fetching comments from the database on every page load, we can cache the comments using the *"use cache"* directive to reduce DB calls.

*getComments.ts*

```JavaScript
"use server";

import { db } from "@/db";
import { comments } from "@/schema";

import { unstable_cacheLife, unstable_cacheTag } from "next/cache";

export async function getComments() {
  "use cache";

  unstable_cacheLife("days");
  unstable_cacheTag("comments");

  const result = await db.select().from(comments).all();
  return result;
}
```

**`unstable_cacheLife`** sets the cache with a specific profile (e.g., “days”). Profiles such as “hours,” “max,” and “weeks” are also available, custom profiles can be created in next.config.ts. The documentation recommends using profiles, though you can set cache parameters like stale, revalidate, and expire manually if needed.

`**unstable_cacheTag**` tags the cache entry with a unique identifier (very similar to the indentifier in `tanstack-query`). It helps with:

- **Tracking and managing the cache**: This tag is used to reference the cached comments data so you can easily manage it.
- **Cache invalidation**: When the comments cache becomes outdated (e.g., when a new comment is added), you can invalidate the cache using this tag to ensure fresh data is fetched the next time comments are requested.

### Method 2: Inserting Comments and Invalidating Cache

In this method, after inserting the comment into the database, we use *`revalidateTag`* to invalidate the relevant cache. This ensures that the next time comments are fetched, the cache will be cleared, and fresh data will be retrieved. 

*createComment.ts*

```JavaScript
"use server";

import { db } from "@/db";
import { comments } from "@/schema";
import { revalidatePath, revalidateTag } from "next/cache";

export async function createComment(formData) {
  const message = formData.get("message");
  const insertedComment = await db.insert(comments).values({ message });

  // Invalidate cache
  revalidateTag("comments");

  return insertedComment;
}
```

### Conclusion

By leveraging Next.js’s *`"use cache"`* directive, we have fine-grained control over how frequently accessed data like comments is fetched. This flexibility improves performance and user experience by reducing unnecessary refetching while keeping data up-to-date through cache invalidation.