hmk run dev
Next.js 서버사이드 keep alive 본문
Next.js 프로젝트에서 백엔드 API와 통신할 때, 우리는 종종 브라우저 또는 서버(SSR/API 라우트 등)에서 외부 서버로 HTTP 요청을 보냅니다. 이때 성능 최적화를 고려한다면 "keep-alive" 설정을 살펴볼 필요가 있습니다.
- 브라우저에서 keep-alive는 어떻게 작동할까?
- 서버 → 서버 요청에서는 왜 명시적으로 설정이 필요할까?
- 실제로 어떻게 적용할 수 있을까?
HTTP keep-alive란?
기본적으로 HTTP 요청은 다음 흐름을 따릅니다:
연결 열기 → 요청 보내기 → 응답 받기 → 연결 닫기
이런 구조는 요청마다 새로운 TCP 연결을 만들고 끊는 비효율을 초래합니다. 특히, 서버 → 서버 간에 수백~수천 개의 API 호출이 일어난다면 이 비용은 무시할 수 없습니다.
keep-alive는 이 문제를 해결하는 방식입니다. 한 번 연결한 TCP 소켓을 재사용해서 여러 HTTP 요청을 보낼 수 있게 합니다.
브라우저에서는 어떻게 동작할까?
브라우저는 기본적으로 HTTP/1.1을 기반으로 하기 때문에, keep-alive는 디폴트로 활성화되어 있습니다.
즉, 클라이언트 사이드에서 fetch, axios 등을 통해 요청을 보낼 때는 특별한 설정 없이도 연결이 재사용됩니다.
하지만 이 연결은 브라우저가 내부적으로 관리합니다:
- 같은 origin 요청끼리만 재사용
- 연결 수 제한 있음 (도메인당 6개 등)
- idle timeout이 적용됨
요약: 브라우저는 알아서 keep-alive를 잘 관리하니, 따로 설정할 필요는 없습니다.
서버 → 서버 요청에서는?
반대로, Next.js 서버에서 실행되는 코드 (예: getServerSideProps, API Route 등) 는 Node.js의 http 모듈을 기반으로 동작합니다.
Node.js의 기본 설정은 keepAlive: false이기 때문에, 매 요청마다 TCP 연결을 새로 생성하게 됩니다.
이럴 경우 다음을 명시적으로 설정해야 합니다:
1. node-fetch + http.Agent
import fetch from 'node-fetch';
import http from 'http';
const keepAliveAgent = new http.Agent({ keepAlive: true });
await fetch('https://api.example.com/data', {
agent: keepAliveAgent,
});
2. undici – 더 빠르고 공식 추천되는 방식
import { fetch, Agent } from 'undici';
const agent = new Agent({
keepAliveTimeout: 10_000, // idle 상태에서 유지할 시간
keepAliveMaxTimeout: 15_000, // 최대 연결 유지 시간
});
await fetch('https://api.example.com/data', {
dispatcher: agent,
});
3. axios 사용 시
import axios from 'axios';
import http from 'http';
const httpAgent = new http.Agent({ keepAlive: true });
const response = await axios.get('https://api.example.com/data', {
httpAgent,
});
언제 keep-alive를 쓰는 게 좋을까?
다음 조건에 해당한다면 적극 도입을 고려하세요:
- 같은 서버에 반복적으로 요청하는 구조 (ex. 내부 API Gateway, 백엔드 서버)
- 대량의 API 호출이 한 페이지 내에서 이뤄지는 구조
- SSR에서 응답 속도 개선이 필요한 경우
마무리
- 브라우저는 keep-alive를 자동으로 관리하므로 따로 신경 쓸 필요 없음
- 서버 측에서는 Agent를 직접 설정하지 않으면 요청마다 새로운 TCP 연결이 열림
- keep-alive 설정만으로도 평균 요청 시간이나 서버 부하가 눈에 띄게 개선될 수 있음
팀에서 성능 개선을 논의 중이라면, 이 설정이 적용되어 있는지 한번 확인해보세요.
특히 getServerSideProps, API Route, 혹은 백엔드 간 통신을 자주 쓰는 구조라면 꽤 큰 차이를 만들어낼 수 있습니다.
'Front-End' 카테고리의 다른 글
Next.js에서 SEO 최적의 렌더링 전략 (0) | 2025.04.25 |
---|---|
Next.js 상황에 맞는 렌더링 방식 선택 가이드 (0) | 2025.04.25 |
레거시를 만들지 않기 위한 습관 (0) | 2024.12.15 |
yarn plugin으로 우아하게 로깅하기 (0) | 2024.10.20 |
프론트엔드의 표준 (HTML, CSS, 크로스브라우징, 브라우저퍼포먼스, 웹 접근성) (0) | 2024.09.29 |