DEV Community

Cover image for ๐Ÿš€ Optimizing Database Queries in Next.js 15 with cache and Prisma
Saiful Islam
Saiful Islam

Posted on

๐Ÿš€ Optimizing Database Queries in Next.js 15 with cache and Prisma

Fetching data efficiently in a Next.js application is crucial for performance. With Next.js 15 and React 18, we can leverage the cache function to optimize database queries and prevent redundant fetches.

In this article, weโ€™ll explore:

  • Why caching is essential
  • How to use cache with Prisma
  • Implementing a cached function to fetch posts in Next.js 15
  • Example usage in a Next.js 15 page

๐Ÿ“Œ Why Use cache for Database Queries?

When querying a database inside a React Server Component or a Next.js API route, we want to minimize redundant queries to reduce database load and improve performance.

The cache function memoizes the result, so repeated calls with the same parameters return the cached response instead of making a new query.

๐Ÿ† Benefits of Using cache with Prisma

โœ… Reduces duplicate database queries
โœ… Improves server performance
โœ… Enhances response time in Server Components
โœ… Works seamlessly with Next.js and React 18


๐Ÿ› ๏ธ Implementing cache with Prisma in Next.js 15

Letโ€™s create a cached function to fetch a post by its slug.

๐Ÿ”น Step 1: Create the Cached Function

Weโ€™ll define getPostBySlug inside a server utility file (e.g., src/lib/posts.ts).

import db from "@/lib/db";
import { cache } from "react";
import { notFound } from "next/navigation";
import { type Prisma } from "@prisma/client";

/**
 * Fetch a blog post by its slug and cache the result
 */
export const getPostBySlug = cache(
  async <T extends Omit<Prisma.PostFindUniqueArgs, "where">>(
    slug: string,
    options?: T,
  ): Promise<Prisma.PostGetPayload<T>> => {
    const post = await db.post.findUnique({
      where: { slug },
      ...options,
    });

    if (!post) return notFound();

    return post as Prisma.PostGetPayload<T>;
  },
);
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”น Step 2: Using getPostBySlug in a Next.js 15 Page

Now, letโ€™s use this function inside a Server Component in Next.js.

import { getPostBySlug } from "@/lib/posts";

export const dynamic = "force-dynamic"; // Ensures the page revalidates

export default async function PostPage({ params }: { params: { slug: string } }) {
  const post = await getPostBySlug(params.slug);

  return (
    <main className="max-w-3xl mx-auto p-6">
      <h1 className="text-4xl font-bold">{post.title}</h1>
      <p className="text-gray-600">{post.publishedAt}</p>
      <article className="mt-6">{post.content}</article>
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

โš ๏ธ Important Considerations

1๏ธโƒฃ Cache Invalidation

  • The cache function caches data for the duration of the request lifecycle.
  • If data updates frequently, use revalidatePath() to manually refresh the cache.

Using cache in Server Components

  • cache is only available in the server environment, meaning it won't work in client components.

3๏ธโƒฃ Database Connection Best Practices

  • Ensure that Prisma is set up correctly with connection pooling when using in a serverless environment (e.g., Vercel, AWS Lambda).

๐ŸŽฏ Conclusion

Using cache in Next.js 15 with Prisma significantly improves performance by reducing redundant database queries. This approach is ideal for caching blog posts, user profiles, or frequently accessed data in a server-side environment.

Have you used cache in your Next.js projects? Letโ€™s discuss in the comments! ๐Ÿš€

Top comments (4)

Collapse
 
silviaodwyer profile image
Silvia O'Dwyer

Excellent guide, I found it very useful!

Collapse
 
saiful7778 profile image
Saiful Islam

Thank you.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.