JavaScript 서버가 이미 떠 있으면 요청을 받자마자 코드를 실행할 수 있어. 하지만 서버리스 함수나 에지 실행 환경처럼 작업이 없을 때 실행 공간을 내려놓는 구조에서는 첫 요청 앞에 준비 시간이 붙어. 이때 처음 실행하는 데 걸리는 시간을 콜드 스타트라고 해.
콜드 스타트는 런타임 하나의 숫자가 아니야. 실행 파일과 엔진을 준비하고, 필요한 모듈을 찾고 읽고 해석한 다음, 애플리케이션의 초기화 코드를 돌리는 여러 비용이 합쳐진 시간이야. 그래서 “런타임이 빠르다”는 말보다 어느 단계의 시간을 재고 있는지가 더 중요해.
한 줄로 말하면
JavaScript 런타임의 콜드 스타트는 코드가 실행되기 전 런타임 준비·모듈 해석·초기화 비용을 한꺼번에 읽는 지표야.
비유로 이해하기
카페에 비유하면 이래. 따뜻한 커피가 이미 나와 있는 상태에서 주문을 받는 건 웜 스타트야. 반대로 문을 닫았다가 다시 연 카페라면 불을 켜고, 원두와 잔을 꺼내고, 주문에 필요한 재료를 준비해야 하지. 첫 손님이 기다리는 시간에는 커피를 만드는 시간만 들어 있지 않아.
다만 이 비유에는 한계가 있어. JavaScript 실행은 카페처럼 한 번 준비한 물건을 그대로 쓰는 일이 아니라, 실행 환경과 모듈 상태를 다시 구성하는 과정이야. 어떤 환경은 준비한 런타임을 다음 요청에 남겨두고, 어떤 환경은 더 자주 새로 시작하므로 같은 코드도 체감 지연이 달라질 수 있어.
정확한 정의
콜드 스타트는 유휴 상태의 실행 환경이 애플리케이션의 첫 작업을 처리할 수 있는 상태가 되기까지의 지연이야. JavaScript에서는 보통 다음 비용을 나눠 생각할 수 있어.
flowchart LR A[유휴 실행 환경] --> B[런타임과 엔진 준비] B --> C[모듈 찾기·읽기·해석] C --> D[애플리케이션 초기화] D --> E[첫 요청 처리] E --> F[다음 요청은 웜 스타트일 수 있음]
런타임과 엔진 준비는 JavaScript를 실행할 기반을 올리는 단계야. 모듈 해석은 import나 패키지 의존성을 따라가며 실행할 코드를 찾고 준비하는 과정이고, 초기화는 애플리케이션이 시작될 때 작성한 설정·라우트·객체 생성을 수행하는 단계야. 실제 시스템에서는 이 단계들이 겹치거나 캐시될 수 있지만, 지연의 원인을 살필 때는 이렇게 나누면 어디가 무거운지 질문하기 쉬워져.
왜 중요한가
서버리스와 에지 실행에서는 짧은 요청을 많이 처리할수록 첫 실행 비용이 전체 응답 시간에서 커질 수 있어. 특히 애플리케이션이 작더라도 의존성 모듈이 많거나 초기화 코드가 무거우면, 함수가 실제 일을 하기 전에 기다리는 시간이 생겨.
반대로 콜드 스타트 숫자가 짧다고 해서 모든 요청이 빠르다는 뜻은 아니야. 네트워크 왕복, 데이터베이스 연결, 첫 요청의 실제 처리 시간은 별도의 비용이야. 콜드 스타트는 그중 실행 환경이 준비되는 구간을 보는 지표에 가깝지.
실제 예시
Ant라는 JavaScript 런타임은 Hono를 불러오고 라우트 두 개를 등록한 뒤 종료하는 예제로 모듈 해석과 초기화 비용을 측정했다고 소개해. 그 조건에서 Ant 5.4ms, Bun 12.8ms, Deno 24.8ms, Node.js 31.1ms를 제시했어.1
이 숫자는 콜드 스타트라는 말을 구체적으로 읽는 데 도움이 돼. 측정 대상이 “Hono를 읽고 라우트를 등록한 뒤 끝나는 프로그램”이기 때문이야. 데이터베이스 연결이나 실제 요청 처리까지 포함한 애플리케이션 전체의 지연을 비교한 결과는 아니야. 숫자의 크기보다 먼저 측정 조건을 확인해야 하는 이유가 여기 있어.
Ant는 약 8.6MB의 단일 바이너리와 자체 개발한 엔진을 내세우고, TypeScript를 ant app.ts로 직접 실행하며 파일의 기본 fetch export를 서버로 제공한다고 설명해. 이런 구성은 실행 전 필요한 단계와 도구를 줄이는 방식으로 콜드 스타트와 개발 흐름에 영향을 줄 수 있지만, 각 기능이 실제 지연을 얼마나 줄이는지는 별도의 측정이 필요해.1
헷갈리지 말아야 할 점
첫째, 콜드 스타트와 웜 스타트는 같은 프로그램의 서로 다른 실행 상태를 가리켜. 이미 실행 환경과 모듈 상태가 남아 있으면 첫 준비 비용을 다시 내지 않을 수 있어. 따라서 평균 지연만 보지 말고 첫 실행과 재사용 실행을 나눠 봐야 해.
둘째, 런타임의 시작 속도와 애플리케이션의 시작 속도는 달라. 작은 실행 파일과 빠른 엔진은 런타임 준비에 영향을 줄 수 있지만, 애플리케이션이 불러오는 모듈 수와 초기화 작업까지 자동으로 가볍게 만들지는 않아.
셋째, 벤치마크의 숫자는 조건을 벗어나면 그대로 옮길 수 없어. Ant의 예시는 특정 프레임워크와 라우트 수를 사용한 짧은 측정이야. 다른 하드웨어, 다른 의존성 그래프, 다른 초기화 작업에서는 모듈 해석과 초기화 비용의 비중이 달라질 수 있어.
관련 문서
Ant가 제시한 실행 환경과 측정 조건은 Ant가 8.6MB 단일 바이너리에 넣은 것에서 더 자세히 볼 수 있어. 앞으로 서버리스·에지 실행에서 패키지 그래프와 실행 환경 재사용을 비교하는 글이 쌓이면 이 개념을 그 문서들과 함께 읽을 수 있어.
댓글