Next.js API Caching Explained: Why Your Data Might Be Stale (and How to Fix It)

🧐 Introduction

Next JS API Calling that gives Cached Data Instead of updated DB Data

If you’ve ever built a Next.js application or any application and noticed your API is returning old or outdated data, even though the database has been updated, you’re not alone.
This is a common confusion for developers new to Next.js’ server-side fetch caching.

In this article, we’ll explore:

  • Why this happens in both development and production.

  • How Next.js fetch caching works.

  • How to disable it when you need fresh data.

  • The SEO impact of different fetching methods.

💡 The Problem

Imagine you have an API route:

pages/api/setting/notifications.ts
export default async function handler(req, res) { const settings = await db.query("SELECT * FROM notification_settings LIMIT 1"); res.json({ data: settings }); }


Now you fetch it in your server code:

js
const resp = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/settings/notifications`); const data = await resp.json();

The issue?
Next.js caches this request by default — sometimes in memory, sometimes in .next/cache — so it might serve an old copy of the data.


🛠 Why It Happens

Next.js optimizes server fetch() calls by:

  • Storing the result in memory to avoid duplicate calls.

  • Serving cached data across requests if no cache or revalidate option is provided.

  • Short-circuiting internal requests so they never hit your API route at all.

This is great for performance, but dangerous for dynamic data.


Does this is a Development centred or it elopes in Production too?

🚨 Production vs Development

  • In Development: Cache is less aggressive because of hot reload.

  • In Production: Cache can persist for hours or indefinitely until revalidation, especially if you deploy to Vercel or another platform.

That’s why many devs only notice this after deploying.

🛡 How to Fix It

To always get fresh data, disable caching in your server fetch:

js
const resp = await fetch(url, { cache: "no-store" }); // or const resp = await fetch(url, { next: { revalidate: 0 } });

Or better — instead of calling your own API from the server, import the database query directly in your server code:

js

import { getNotificationSettings } from "@/lib/db"; const settings = await getNotificationSettings();





By: Shivam Dixit ( https://shivamdixit.engineer )
Organisation: Seoulix Technologies
Date: 08/11/2025 11:30 PM

Comments

Pageviews