Next.js Memory Usage 가이드 정리

1. 개요

Next.js 프로젝트는 **개발 서버(next dev)**와 빌드(next build) 과정에서 상황에 따라 메모리(특히 Node.js heap)를 많이 사용할 수 있습니다.
이 가이드는 “메모리 부족(OOM)”이나 빌드/개발 과정의 비정상적인 메모리 사용 증가를 줄이기 위한 공식 문서 기반 체크리스트를 정리한 것입니다.

핵심: **문제 구간을 먼저 특정(Dev vs Build, Webpack vs TypeScript, Source map 등)**한 뒤, 해당 구간의 옵션을 단계적으로 적용합니다.


2. 증상 체크

다음 같은 상황이면 “메모리 이슈” 가능성이 큽니다.

  • next build 중 프로세스가 종료되거나 OOM으로 실패
  • “Generating static pages” 단계(프리렌더)에서 메모리 급증
  • next dev 시작/핫리로드 시 메모리 사용량이 계속 증가
  • CI 환경에서만 빌드가 간헐적으로 실패

3. 대응 전략 (우선순위 순)

3.1 의존성(번들) 최적화

의존성이 과도하면 빌드/번들링 단계에서 메모리도 크게 증가합니다.

  • 사용하지 않는 패키지 제거
  • 동일 기능 중복 패키지 제거(예: 여러 date 라이브러리 혼용)
  • 가능한 경우 tree-shaking이 잘 되는 패키지로 교체
  • 번들 분석 도구로 “큰 덩어리”부터 정리

3.2 Webpack 메모리 최적화 플래그 사용

Webpack 기반 빌드에서 메모리 문제가 심하면, Next.js 설정의 실험 플래그로 개선을 시도할 수 있습니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  experimental: {
    webpackMemoryOptimizations: true,
  },
}

export default config

3.3 빌드 메모리 사용 디버깅(원인 파악)

빌드에서 어떤 단계가 메모리를 먹는지 추적하는 로그를 켭니다.

NEXT_DEBUG_MEMORY_USAGE=1 next build
  • 어떤 단계에서 급증하는지 확인 후, 아래 옵션(소스맵/TS/캐시 등)을 선택 적용합니다.

3.4 Webpack “빌드 워커” 활성화

Webpack 작업을 별도 워커에서 처리하도록 하여 메모리/성능 개선을 시도합니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  experimental: {
    webpackBuildWorker: true,
  },
}

export default config

3.5 Webpack 캐시 비활성화

캐시가 오히려 메모리를 많이 쓰거나 CI에서 불안정하면 끄는 것이 도움이 될 수 있습니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  webpack: (config) => {
    config.cache = false
    return config
  },
}

export default config

3.6 TypeScript 정적 분석(타입 체크) 비활성화 (주의)

타입 체크 때문에 메모리가 부족한 경우, 빌드 단계에서 타입 체크를 끌 수 있습니다.
단, 타입 에러가 있는 상태로 배포될 수 있으므로 운영 배포 파이프라인에서는 신중해야 합니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  typescript: {
    // !! WARN !!
    // 프로덕션 배포에 바로 적용하기 전에, 별도 타입체크 스텝을 CI에서 반드시 보장하는 것을 권장
    ignoreBuildErrors: true,
  },
}

export default config

권장 운영 방식(예시):

  • CI 단계에서 tsc --noEmit을 “필수 통과”로 두고
  • Next 빌드에서는 타입 체크를 끄는 방식으로 역할을 분리

3.7 Source map 비활성화

소스맵 생성은 빌드 메모리를 많이 사용합니다.
특히 **프리렌더 단계(“Generating static pages”)**에서 문제가 나면, 해당 단계용 소스맵 옵션도 함께 조정할 수 있습니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  productionBrowserSourceMaps: false,
  experimental: {
    serverSourceMaps: false,
    // 프리렌더 단계에서 source map이 기본으로 켜지는 경우가 있어, 문제가 계속되면 꺼볼 수 있음
    enablePrerenderSourceMaps: false,
  },
}

export default config

3.8 Edge runtime 메모리 이슈(버전 확인)

Edge runtime 사용 시 특정 버전에서 메모리 이슈가 있었고, Next.js v14.1.3에서 수정되었다고 안내합니다.
Edge를 쓰고 있고 메모리 문제가 있다면, Next.js 버전을 최신으로 올리는 것부터 확인합니다.


3.9 서버 시작 시 엔트리(페이지) 프리로드 비활성화

서버 시작 시 모든 페이지 모듈을 미리 메모리에 올리는 최적화가 있습니다.
초기 메모리 풋프린트가 문제라면 끌 수 있습니다.

// next.config.ts
import type { NextConfig } from 'next'

const config: NextConfig = {
  experimental: {
    preloadEntriesOnStart: false,
  },
}

export default config

참고: 이 최적화를 꺼도, 결국 “페이지가 한 번씩 요청되면” 모듈이 메모리에 올라가므로 장기적으로 동일 수준이 될 수 있습니다.


4. 실전 적용 순서(권장)

  1. NEXT_DEBUG_MEMORY_USAGE=1 next build폭증 단계 확인
  2. (빌드 문제면) productionBrowserSourceMaps, experimental.serverSourceMaps, enablePrerenderSourceMaps 끄기
  3. (Webpack 문제면) experimental.webpackMemoryOptimizations, experimental.webpackBuildWorker 켜기
  4. (캐시 문제면) config.cache=false 적용
  5. (TypeScript 문제면) typescript.ignoreBuildErrors마지막 카드로 사용 + CI 타입체크 필수화
  6. 서버 런타임 초기 메모리라면 experimental.preloadEntriesOnStart=false