Next.js 미들웨어에서 fetch 캐싱이 실패하는 이유

2025.07.04
대표 이미지

Next.js 미들웨어에서 fetch 캐시가 동작하지 않는 문제와 대응 방식

이번 포스트는 **Next.js의 미들웨어 환경**에서 `fetch`를 사용할 때 발생하는 캐시 미적용 문제를 정리한 것이다. 특히 `next-auth`를 함께 사용하는 구조에서, **중복된 네트워크 요청**이 발생하는 사례와 그 해결 방안을 설명한다.



문제 상황

App Router 기반의 Next.js 프로젝트에서 다음과 같은 방식으로 사용자 세션 검증을 수행했다:

  1. 모든 요청마다 `middleware.ts`가 실행된다.

  2. `middleware` 내에서 `next-auth``getToken()` 혹은 `getServerSession()`을 호출한다.

  3. 이 함수들은 내부적으로 `fetch`를 사용해 서버 세션 정보를 조회한다.


이 구조는 로컬 개발 환경뿐 아니라 Vercel 배포 환경에서도 **같은 요청에 대해 다수의 중복 fetch 요청이 발생하는 문제**를 유발했다.

그 원인은 **Next.js의 `middleware.ts`는 공식적으로 fetch 캐시 최적화의 대상이 아니기 때문**이다.


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

[공식 문서 링크](https://nextjs.org/docs/14/app/building-your-application/data-fetching/fetching-caching-and-revalidating?utm_source=chatgpt.com)


Next.js 14 기준의 문서이지만, 15에서도 해당 동작은 동일하게 유지되고 있다.

즉, 미들웨어에서의 fetch는 **항상 네트워크 요청을 발생시키며 캐시 또는 deduplication이 적용되지 않는다**.



문제 분석

Next.js는 특정 실행 컨텍스트(Server Component, Route Handler, Server Action) 내에서만 `fetch`에 대해 캐시 및 자동 재검증 기능을 제공한다.

결과적으로 미들웨어 내에서 **세션 조회 같은 정적인 요청이여도 매번 새로운 fetch가 수행되며**, 인증 서버 또는 내부 API에 과도한 부하를 줄 수 있다.



해결 방안

다음과 같이 구조를 변경했다:

  • 미들웨어를 `next-auth``auth()`함수가 아닌 기본 `middleware`로 변경

  • 사용자 세션 검증 로직은 **API 라우터 또는 서버 컴포넌트 내부로 이전**

  • 미들웨어는 URI 기반 필터링, 정적 리다이렉트 등 **최소한의 경량 로직만 담당**


또한, Vercel 기준으로 `middleware.ts`는 Edge Function으로 실행되며, **요금 측정의 단위**가 된다.

이에 따라 Vercel 공식 가이드에서도 미들웨어 사용을 최소화할 것을 명시하고 있다.

불필요한 fetch 요청을 줄이는 것은 비용 측면에서도 중요하다.



참고 사항

  • `next-auth`의 middleware에 사용되는 `auth()` 함수는 내부에서 `sessionCallback` 실행한다. (callback에 fetch가 있는 경우 캐시 없이 실행된다)

  • 해당 fetch는 middleware에서 실행될 경우 **매 요청마다 중복 수행되며**, SSR 캐시나 deduplication은 적용되지 않는다.

  • `next-auth`의 공식 문서에서도 미들웨어 내 사용은 별도로 권장되지 않는다.



결론

Next.js의 미들웨어는 `fetch` 캐시 기능을 지원하지 않기 때문에, **데이터 접근이 필요한 로직은 서버 컴포넌트나 route handler에서 처리해야 한다.**

세션 검사처럼 반복 호출이 발생하는 로직은 **미들웨어에서 제거**해야 하며,

구조적으로 안전하면서도 성능 저하를 피하기 위해 **책임 분리를 명확하게 적용**해야 한다.

Next.js 미들웨어에서 fetch 캐싱이 실패하는 이유 - sim-log