Incremental Static Regeneration (ISR) - Page Router
ISR이란?

ISR은 SSG의 장점은 유지하면서 데이터 최신성 문제를 보완하기 위한 렌더링 방식이다.
빌드 시점에 HTML을 미리 생성하지만, 배포 이후에도 일정 주기로 페이지를 다시 생성할 수 있다.
즉, 정적 페이지의 성능을 유지하면서 데이터를 갱신할 수 있는 방식이다.
Next.js Page Router에서는 getStaticProps의 revalidate 옵션을 통해 ISR을 사용할 수 있다.
export const getStaticProps = async () => {
console.log('인덱스 페이지');
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
]);
return {
props: {
allBooks,
recoBooks,
},
revalidate: 3,
};
};왜 ISR이 필요할까?
SSG의 구조적인 한계
- 최신 데이터 반영이 어렵다.
- 데이터 변경 시 재빌드가 필요하다.
완전히 실시간일 필요는 없지만, 빌드 시점에 데이터가 고정되는 것도 애매한 화면들이 존재한다.
즉, 완전 실시간은 아니지만 최신성이 중요한 화면!
- 게시글 목록
- 블로그 목록
- 뉴스 목록
- 랭킹 페이지
- 상품 목록
- 통계 / 대시보드 요약 화면
이러한 요구를 해결하기 위한 방식이 바로 ISR이다.
ISR의 동작 특성
- 기본적으로 정적 페이지로 동작
- 일정 주기 이후 요청 기반 재생성
- SSR 대비 서버 부담 감소
- SSG 대비 데이터 최신성 확보
getStaticProps + revalidate
ISR은 기존 SSG 코드에 옵션 하나만 추가하면 된다.
export const getStaticProps = async () => {
const books = await fetchBooks();
return {
props: {
books,
},
revalidate: 60, // 60초마다 갱신
};
};- 이 페이지를 최소 60초 동안 캐싱하고, 이후 새로운 요청이 들어올 때 재생성이 트리거된다.
revalidate는 페이지의 유효 기간(TTL)처럼 동작한다.
TTL (Time To Live)
TTL은 캐시의 유효 기간을 의미한다.
설정된 시간이 지나기 전까지는 기존 HTML이 그대로 응답된다.
revalidate 동작 방식
revalidate: 3
- 빌드 시점
- HTML 생성
- 정적 페이지로 배포
🔍 Next.js 빌드 결과 (ISR 적용)

- 배포 이후 요청
- 캐시된 HTML 응답 (SSG처럼 빠름)
- 3초 이후 새로운 요청 발생 시
- 기존 캐시된 페이지 먼저 응답
- 서버에서 백그라운드 재생성 수행
- 생성 완료 후 캐시 교체
즉, 최초 요청까지는 완전한 정적 페이지처럼 동작하고, 이후에는 요청 기반으로 점진적 재생성이 수행된다.
ISR은 SSG와 SSR 사이에서 성능과 최신성의 균형을 맞추기 위한 전략이라고 볼 수 있다!
On-Demand ISR (수동 재생성)
위의 ISR은 revalidate 값을 기준으로 동작하는 시간 기반 재생성 방식이다.
하지만 실제 서비스에서는 단순한 시간 주기보다 특정 이벤트 시점에 즉시 갱신이 필요한 경우가 더 많다.
- 게시글 수정 즉시 반영
- 관리자가 업데이트 버튼 누르면 갱신
- 특정 이벤트 발생 시 캐시 무효화
이럴 때 사용하는 방식이 바로 On-Demand ISR이다.
시간 주기가 아닌 사용자의 요청 또는 이벤트를 기준으로 페이지 재생성을 트리거하는 방식이다.
getStaticProps에서 revalidate 제거
시간 기반 ISR 대신 수동 재생성을 사용할 경우, 페이지는 기본적으로 SSG로 고정된다.
export const getStaticProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
]);
return { props: { allBooks, recoBooks } };
};revalidate옵션 제거- 페이지는 빌드 시점에만 생성되는 순수 SSG
즉, 자동 재생성은 일어나지 않는다.
API Route에서 수동 재생성
페이지 재생성은 별도의 API Route에서 직접 트리거한다./api/revalidate.ts
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
try {
await res.revalidate('/');
return res.json({ revalidate: true });
} catch (err) {
console.error(err);
res.status(500).send('Revalidation Failed');
}
}await res.revalidate('/');
- 지정한 경로
/의 정적 페이지 캐시를 무효화 - 새로운 HTML 재생성 트리거
즉, 자동 갱신이 아니라 명시적인 트리거 기반 ISR 방식이다.
On-Demand ISR의 핵심 개념
- 페이지 자체는 SSG로 유지
- 재생성 시점만 명시적으로 제어
- CMS 연동, 관리자 액션 등 변경 시점이 명확할 때 적합