serverless성능vercel
서버리스 콜드 스타트, 실측으로 배운 것들
✨ AI 요약
긴 글, 핵심만 먼저 — 이 글을 3줄로 정리해드려요.
조회 28
서버리스의 숨은 세금이 콜드 스타트다. 트래픽이 적은 서비스일수록 더 자주 맞는다는 게 역설이다. 실측하며 배운 것들을 정리한다.
콜드 스타트의 구성
전체 지연 = 컨테이너 기동 + 런타임 초기화 + 모듈 로드 + 핸들러 실행. 통제 가능한 건 모듈 로드다. 우리 측정에서 전체 800ms 중 500ms가 import 비용이었다.
1. import 다이어트가 본질
// 파일 상단 — 콜드 스타트마다 로드됨
import { HeavySDK } from "heavy-sdk"; // 300ms
// 핸들러 안 dynamic import — 쓰는 요청만 부담
const { HeavySDK } = await import("heavy-sdk");
AWS SDK, 이미지 처리, PDF 생성 같은 무거운 모듈은 함수 최상단 import에서 빼는 것만으로 콜드 스타트가 수백 ms 준다. 번들 분석기로 함수별 번들 크기를 보는 게 첫걸음이다.
2. 커넥션은 핸들러 밖에서 재사용
// 모듈 스코프 — 웜 인스턴스에서 재사용
const prisma = globalThis.prisma ?? new PrismaClient();
핸들러 안에서 매번 커넥션을 만들면 웜 요청까지 느려진다. 반대로 모듈 스코프에 두면 콜드엔 어쩔 수 없지만 웜은 0ms다. 서버리스 + DB는 커넥션 풀러(pgbouncer 등)와 조합해야 커넥션 고갈을 피한다.
3. 리전이 절반이다
함수와 DB가 다른 리전이면 왕복마다 수십~수백 ms를 낸다. 함수-DB-사용자를 같은 지역에 모으는 게 코드 최적화 전부를 합친 것보다 효과가 컸다. 우리는 서울 리전 통일로 p95가 60% 내려갔다.
4. 예열은 마지막 수단
크론으로 주기 호출하는 예열은 동시 요청이 오면 결국 새 인스턴스가 뜨므로 근본 해결이 아니다. 트래픽이 진짜 중요한 엔드포인트 한두 개에만, 그것도 위 3가지를 다 한 뒤에 고려하자.