간헐적 트래픽 API에서 콜드스타트는 왜 비용 문제가 되나?

요청 수는 그대로인데 비용만 늘었다면, 콜드스타트 초기화 구간이 2025년 8월부터 실행 시간과 같은 방식으로 과금되기 시작했다는 점을 먼저 의심해야 한다. 간헐적 트래픽과 무거운 의존성을 가진 서비스는 분기 컴퓨트 비용의 5~15%까지 콜드스타트에서 나온다는 분석도 있다.출처 판단 기준은 호출당 가격이 아니라, 메모리·번들·초기화 로직을 함께 바꿨을 때의 p99 기준 총 GB-second 비용이다.

  • 2025년 8월부터 Lambda의 INIT duration은 실행 시간과 동일하게 과금된다
  • 간헐적 트래픽 서비스는 콜드스타트 비용이 분기 컴퓨트 비용의 5~15%까지 올라갈 수 있고, 작은 번들·워밍 풀 조합에서는 2% 미만으로 낮아질 수 있다
  • 메모리를 늘리면 호출 단가는 오르지만 실행 시간이 줄어 총비용이 내려갈 수도, 안 내려갈 수도 있다 — 반드시 둘을 같이 봐야 한다
  • Java는 런타임 자체보다 프레임워크 초기화가 콜드스타트의 대부분을 차지한다

지난 분기 말, 사내 정산 조회 API의 Lambda 청구액이 전월 대비 늘었다는 알림을 받았다. 트래픽 로그상 요청 수는 거의 그대로였고 동시성도 평소 수준이었는데, 청구서의 GB-second 항목만 눈에 띄게 커져 있었다. 그래프를 확인해보니 비용 증가가 균일하지 않고, 출근 직후와 점심 직후 같은 특정 시간대에 계단식으로 튀는 패턴이었다.

요청 수는 그대로인데 왜 GB-second만 늘었을까?

먼저 과금 방식 자체가 바뀌었을 가능성부터 확인했다. 2025년 8월 변경 공지를 다시 찾아보니, 콜드스타트 초기화 구간(INIT duration)이 함수 실행 시간과 같은 방식으로 과금된다는 내용이 있었다.출처 이 서비스는 512MB 메모리로 설정돼 있었는데, 콜드스타트 초기화가 500ms 발생할 때마다 단순 계산으로 약 0.25 GB-second가 추가되는 구조였다. 요청 패턴이 간헐적이라 콜드스타트 발생 빈도 자체가 높다는 점이 겹쳐, 실제 청구서에서는 이 구간이 무시할 수 없는 비중을 차지하고 있었다.

간헐적 트래픽 구간에서 콜드스타트가 왜 몰렸을까?

이 API는 Java 17 기반이었고, 아침·점심 직후처럼 요청이 몰렸다가 한참 비는 패턴이 반복되는 서비스였다. Lambda 실행 환경은 일정 시간 유휴 상태가 지나면 회수되므로, 트래픽이 재개될 때마다 새 실행 환경이 초기화됐다. 2025년 관측 자료에서 Java 11/17의 평균 콜드스타트는 520~720ms, 중간 규모 번들에서는 중앙값 300~520ms에 90백분위가 700~1,100ms까지 올라가는 범위로 보고됐다.출처 다른 사례에서도 Spring Boot 기반 애플리케이션은 일반적인 초기화 비용이 3~6초 범위로 제시된 바 있다.출처 배포 패키지를 열어보니 프레임워크 의존성이 꽤 크게 묶여 있었고, 핸들러 진입 전에 DB 커넥션 풀과 설정 클라이언트를 모두 초기화하는 구조였다. 이 초기화 블록이 매 콜드스타트마다 반복 실행되고 있었다.

메모리를 늘리면 정말 비용이 내려갈까?

메모리 증설이 콜드스타트와 실행 시간을 동시에 줄여줄 수는 있지만, 호출 단가 자체는 올라가므로 반드시 전체 비용으로 재계산해야 한다. 한 벤치마크 예시에서는 128MB에서 콜드스타트 1,200ms·호출 비용 $0.0000002였던 값이, 1,024MB에서는 콜드스타트 280ms·호출 비용 $0.0000005로 바뀌었다.출처 호출당 단가만 보면 2.5배 비싸 보이지만, 콜드스타트 구간의 GB-second는 오히려 크게 줄어드는 구조다. 이 서비스를 512MB에서 1,024MB로 올렸을 때도 콜드스타트 중앙값이 20~25% 줄어드는 경향이 보고된 범위와 비슷하게 움직였지만,출처 평소 요청량이 적은 야간 시간대에는 메모리 증설분이 그대로 비용으로 남는다는 부작용도 함께 확인됐다.

실제로 재현해서 숫자로 확인했나?

원인을 확정하기 위해 완전히 유휴 상태를 만든 뒤 1회 호출, 5분 간격 호출, 버스트 호출 세 가지 패턴으로 각각 수백 회씩 호출해 p50·p95·p99와 GB-second를 따로 기록했다. 완전 유휴 후 첫 호출에서는 p95 콜드스타트가 기존 설정 기준 약 900ms대까지 나왔고, 이 구간만 따로 떼어 GB-second로 환산하자 전체 실행 GB-second의 상당 부분을 차지하는 것으로 나타났다. 이 수치를 월 단위 호출 횟수에 곱해보니, 청구서에서 눈에 띄게 늘어난 금액과 비슷한 규모가 나왔다. 컴퓨트 단가 $0.00001667/GB-second, 요청당 비용 1백만 건당 $0.20라는 일반 기준으로 재계산했을 때도출처 콜드스타트 구간이 분기 비용 증가분의 대부분을 설명했다.

무엇을 바꿨고 어떤 지표로 확인했나?

크게 세 가지를 바꿨다. 첫째, Lambda SnapStart를 적용해 Java 초기화 구간을 스냅샷 복원 방식으로 바꿨다. 참고한 사례에서는 Java 17·50MB 패키지·1GB 메모리 조건에서 일반 콜드스타트 평균 2,500ms·p99 4,000ms가 SnapStart 적용 후 평균 250ms·p99 450ms로 낮아진 결과가 보고된다.출처 둘째, 핸들러 진입 전 일괄 초기화하던 DB 커넥션과 설정 조회를 지연 초기화로 옮기고 불필요한 의존성을 정리했다. 셋째, 출퇴근·점심 시간대처럼 트래픽이 몰리는 구간에만 한정해 Provisioned Concurrency를 소규모로 적용했다. 2025년 벤치마크에서는 Provisioned Concurrency 적용 시 p95 콜드스타트가 약 2.0초에서 0.35~0.6초로 줄어든 사례가 제시됐고,출처 GB-hour당 추가 비용은 구성에 따라 $0.000004~$0.00002 범위로 제시된다. 변경 후 같은 조건으로 재측정한 결과 p95 콜드스타트와 콜드스타트 구간 GB-second가 눈에 띄게 줄었고, 월 청구서의 증가분도 완화됐다. 다만 Provisioned Concurrency를 야간까지 유지했을 때는 실제 요청이 없는데도 비용이 계속 발생해, 시간대별 스케줄링으로 범위를 좁혔다.

같은 함정을 피하려면 무엇을 기본값으로 삼아야 하나?

콜드스타트는 지연시간 지표가 아니라 청구서 항목으로 봐야 한다는 게 이번 회고의 결론이다. 2026년 기준으로 서버리스 비용을 검토할 때는 호출당 단가만 비교하지 말고, 완전 유휴 후 1회 호출의 p50·p95·p99, 콜드스타트 구간 GB-second, 메모리 단계별 총비용을 함께 기록하는 걸 기본값으로 삼는 편이 안전하다. 특히 Java처럼 초기화 비용이 큰 런타임을 간헐적 트래픽 위에 올릴 때는, SnapStart나 Provisioned Concurrency 같은 선택지의 비용을 "콜드스타트 제거 효과"가 아니라 "유휴 비용 대 SLA 위반 비용"의 비교로 판단해야 한다.

핵심 정리

  • 2025년 8월부터 Lambda INIT duration이 실행 시간과 동일하게 과금되므로, 콜드스타트는 지연시간이 아니라 GB-second 비용 항목이다
  • 간헐적 트래픽 서비스는 콜드스타트 비용이 분기 컴퓨트 비용의 5~15%까지 차지할 수 있고, 작은 번들·워밍 풀 조합에서는 2% 미만까지 낮아질 수 있다
  • 메모리 증설은 호출 단가를 올리지만 실행 시간을 줄여 총비용을 낮출 수도 있어, 호출당 가격이 아니라 전체 GB-second로 비교해야 한다
  • Java는 프레임워크 초기화 비용이 커서 SnapStart 같은 메커니즘의 효과가 크게 나타나는 대표적인 런타임이다
  • Provisioned Concurrency는 피크 구간에 한정해 적용하지 않으면 유휴 시간에도 비용이 계속 쌓인다