autocannon: Node.js HTTP 부하 테스트 단계별 가이드

Node.js 벤치마킹 도구인 autocannon으로 HTTP 엔드포인트를 부하 테스트하세요. 설치하고, -c/-d/-p 옵션으로 실행하며, 지연 시간 백분위수를 확인하고, CI에 스크립트로 구현하세요.

Ashley Innocent

Ashley Innocent

6 July 2026

autocannon: Node.js HTTP 부하 테스트 단계별 가이드

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

HTTP 엔드포인트를 작성했습니다. Postman에서 한 번 호출하면 잘 작동합니다. 하지만 200개의 클라이언트가 동시에 호출하면 어떻게 될까요? 초당 요청 수, 지연 시간 백분위수, 그리고 2xx가 아닌 상태로 돌아온 응답 수와 같은 숫자가 필요합니다. autocannon은 터미널에서 약 10초 만에 이 수치들을 제공합니다.

autocannon은 Node.js로 작성된 HTTP/1.1 벤치마킹 도구입니다. 이 도구는 URL에 대해 제어된 요청 플러드를 발생시키고 처리량과 지연 시간을 보고합니다. 이 가이드는 설치, 기본 실행, 실제로 사용하게 될 모든 플래그, 출력 읽기, 그리고 Node 스크립트에서 autocannon을 사용하는 방법을 안내합니다. 또한 부하 테스트가 알려주는 것과 알려주지 않는 것을 명확하게 구분하여, 기능 및 계약 테스트를 대신 사용해야 할 시점을 알 수 있도록 합니다.

버튼

autocannon이란 무엇인가

autocannon은 URL에 대해 고정된 수의 동시 연결을 열고, 정해진 기간(또는 정해진 요청 수) 동안 계속해서 요청을 보냅니다. 실행되는 동안 지연 시간을 샘플링하고 응답을 카운트합니다. 완료되면 지연 시간 백분위수 표와 총 요청 수 및 읽은 바이트 수에 대한 요약을 출력합니다.

이 도구는 한 가지를 측정합니다: 서버가 얼마나 많은 부하를 처리하고 그 부하 하에서 얼마나 빨리 응답하는지. 응답 본문이 올바른지, API가 OpenAPI 사양과 일치하는지, 또는 다단계 워크플로우가 각 단계에서 올바른 데이터를 반환하는지는 확인하지 않습니다. 이 구분을 명심하십시오. 이는 autocannon이 테스트 스택에서 어디에 적합한지를 결정하며, 이 부분은 끝에서 다룹니다.

만약 wrk 또는 Apache Bench를 사용해본 적이 있다면, autocannon은 Node-native 설치와 JavaScript에서 호출할 수 있는 프로그래밍 API를 통해 같은 역할을 합니다.

설치

autocannon은 npm 패키지로 제공됩니다. 어디서든 autocannon 명령을 사용하려면 전역으로 설치하십시오:

npm i autocannon -g

먼저 Node.js가 설치되어 있어야 합니다. 전역으로 설치하고 싶지 않다면 npx로 필요할 때 실행하세요:

npx autocannon http://localhost:3000

또는 스크립트로 사용할 계획이라면 프로젝트에 개발 종속성으로 추가하세요:

npm i autocannon --save-dev

설치를 확인하십시오:

autocannon --version

기본 실행

가장 간단한 형태는 명령어와 URL입니다. 이는 기본 벤치마크(10초 동안 10개의 연결)를 실행합니다.

autocannon http://localhost:3000

계속해서 사용하게 될 세 가지 플래그로 설정을 조절하세요. -c는 동시 연결 수를 설정하고, -d는 지속 시간을 초 단위로 설정하며, -p는 파이프라이닝(각 연결이 응답을 기다리기 전에 보내는 요청 수)을 설정합니다.

autocannon -c 100 -d 30 -p 10 http://localhost:3000

이 명령어는 100개의 연결을 열고, 30초 동안 실행되며, 연결당 10개의 요청을 파이프라인으로 보냅니다. 연결 및 파이프라이닝 수가 높을수록 더 많은 부하를 발생시키며, 이를 통해 지연 시간이 증가하기 시작하는 지점을 찾을 수 있습니다.

지속 시간 동안 실행하는 대신 고정된 수의 요청을 보내려면 -a (amount)를 사용하세요:

autocannon -c 10 -a 10000 http://localhost:3000

이는 시간과 관계없이 10,000개의 요청 후에 중지됩니다.

POST 요청, 헤더, 그리고 본문

-m으로 메서드를 변경하고, -H로 헤더를 추가하며, -b로 요청 본문을 전달합니다. 다음은 JSON 엔드포인트에 대한 POST 예시입니다:

autocannon -c 50 -d 20 \
  -m POST \
  -H 'Content-Type=application/json' \
  -H 'Authorization=Bearer YOUR_TOKEN' \
  -b '{"name":"load-test","active":true}' \
  http://localhost:3000/api/users

헤더 형식은 -H 'Key=Value'이며, 각 헤더에 대해 -H를 반복합니다. 본문이 크거나 파일에 저장되어 있다면, 인라인으로 입력하는 대신 -i를 사용하여 디스크에서 읽어들이세요:

autocannon -m POST -H 'Content-Type=application/json' -i payload.json http://localhost:3000/api/users

테스트 속도 제한

기본적으로 autocannon은 가능한 한 빠르게 요청을 보냅니다. 때로는 최대 압력으로 요청을 쏟아내는 대신 꾸준하고 현실적인 속도를 원할 수 있습니다. -R은 모든 연결에 걸쳐 초당 총 요청 수를 제한합니다:

autocannon -c 50 -R 500 -d 60 http://localhost:3000

이는 60초 동안 초당 500개의 요청으로 테스트를 유지합니다. 이는 서버의 한계점에서가 아니라 예상되는 프로덕션 부하에서 지연 시간을 측정하고자 할 때 유용합니다.

워밍업 및 워커 스레드

더 무거운 테스트 실행에 도움이 되는 두 가지 플래그가 있습니다. -W (워밍업)는 autocannon이 샘플링을 시작하기 전에 짧은 간격 동안 트래픽을 보내, 첫 번째 숫자가 콜드 캐시나 아직 워밍업되지 않은 JIT에 의해 왜곡되지 않도록 합니다. -w (워커)는 부하를 여러 Node 워커 스레드에 분산시키는데, 이는 단일 스레드가 빠른 서버를 포화시킬 만큼 충분한 요청을 생성할 수 없을 때 중요합니다:

autocannon -c 200 -d 30 -w 4 http://localhost:3000

-w는 부하 생성기 자체가 병목 현상임을 확인한 경우에만 사용하십시오. -c를 높여도 지연 시간이 의심스러울 정도로 평평하게 보인다면, 생성기가 최대치에 도달했을 수 있으며, 워커를 추가하면 서버의 실제 한계를 더 정확하게 파악할 수 있습니다.

결과 읽기

실행이 완료되면 autocannon은 지연 시간 표와 요약 줄을 출력합니다. 간략한 예시는 다음과 같습니다:

http://localhost:3000에서 10초 테스트 실행 중
10개 연결

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬──────────┐
│ 통계    │ 2.5% │ 50%  │ 97.5% │ 99%  │ 평균    │ 표준편차 │ 최대값   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼──────────┤
│ 지연 시간 │ 0 ms │ 1 ms │ 4 ms  │ 6 ms │ 1.2 ms  │ 0.9 ms  │ 24.1 ms  │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴──────────┘

10.05초 동안 251k 요청, 27.9 MB 읽음

읽는 방법은 다음과 같습니다:

두 가지 플래그를 사용하면 출력을 더 유용하게 만들 수 있습니다. -l을 추가하면 전체 지연 시간 백분위수(p99.9 및 그 이상 포함)를 출력하고, --renderStatusCodes를 추가하면 상태 코드별 분석을 볼 수 있어 좋은 처리량 숫자 뒤에 숨어있는 500번대 오류의 급증을 잡아낼 수 있습니다:

autocannon -c 100 -d 20 -l --renderStatusCodes http://localhost:3000

오류, 타임아웃, 2xx가 아닌 응답 수를 주시하십시오. 서버는 높은 요청률을 보이지만 조용히 오류를 반환할 수 있습니다. 2xx가 아닌 응답 수가 0이 아니라면, 처리량 수치는 성공이 아닌 실패를 측정하고 있는 것입니다.

스크립트에서 프로그래밍 방식으로 사용

autocannon은 Node.js API를 노출하므로, 스크립트에서 벤치마크를 실행하고 결과에 따라 조치할 수 있습니다. 자동화에서 이 점이 중요한 역할을 합니다: 테스트를 실행하고, 숫자를 읽고, 지연 시간이 임계값을 초과하면 빌드를 실패시킵니다.

핵심 호출은 옵션 객체를 받아들이고 프로미스를 반환합니다:

const autocannon = require('autocannon')

async function run() {
  const result = await autocannon({
    url: 'http://localhost:3000',
    connections: 100,
    duration: 20,
    pipelining: 1
  })

  console.log(`평균 지연 시간: ${result.latency.average} ms`)
  console.log(`초당 요청 수: ${result.requests.average}`)
  console.log(`2xx 아님: ${result.non2xx}`)
}

run()

result 객체는 latency, requests, throughput에 대한 히스토그램을 포함하며, 각 히스토그램은 average, min, max, 그리고 p99와 같은 백분위수 필드를 가집니다. 또한 errors, timeouts, non2xx 카운트도 포함합니다.

이를 게이트로 만들려면, 예산이 초과될 때 0이 아닌 값으로 종료되는 검사를 추가하세요:

const autocannon = require('autocannon')

const P99_BUDGET_MS = 250

async function run() {
  const result = await autocannon({
    url: 'http://localhost:3000/api/health',
    connections: 100,
    duration: 30
  })

  const p99 = result.latency.p99
  console.log(`p99 지연 시간: ${p99} ms (예산 ${P99_BUDGET_MS} ms)`)

  if (p99 > P99_BUDGET_MS || result.non2xx > 0) {
    console.error('성능 예산을 초과했습니다')
    process.exit(1)
  }
}

run()

CLI가 보여주는 실시간 진행률 표시줄과 결과 테이블을 원한다면, 인스턴스를 autocannon.track에 전달하세요:

const autocannon = require('autocannon')

const instance = autocannon({
  url: 'http://localhost:3000',
  connections: 10,
  duration: 10
}, console.log)

autocannon.track(instance, { renderProgressBar: true })

process.once('SIGINT', () => instance.stop())

다중 요청 시나리오의 경우, 각 연결이 여러 호출을 순환하도록 requests 배열을 전달하세요:

autocannon({
  url: 'http://localhost:3000',
  connections: 20,
  duration: 15,
  requests: [
    { method: 'GET', path: '/api/users' },
    { method: 'POST', path: '/api/data', body: '{"x":1}',
      headers: { 'Content-Type': 'application/json' } }
  ]
}, console.log)

autocannon vs wrk 및 ab

세 가지 모두 동일한 질문(얼마나 빠르고, 얼마나 많은 부하에서)에 답하며, 올바른 선택은 사용하는 스택에 따라 달라집니다.

Node가 런타임이라면 autocannon이 마찰이 적은 선택입니다. Python 도구를 선호하십니까? Python 없이 부하 테스트하는 방법을 참조하십시오. 다양한 기능을 갖춘 스크립팅 가능한 옵션을 원하십니까? k6 부하 테스트와 비교해 보세요.

기능 테스트와 Apidog의 역할

autocannon은 엔드포인트가 p99 40ms에서 초당 12,000개의 요청을 처리한다고 알려줍니다. 하지만 엔드포인트가 올바른 데이터를 반환하는지는 알려주지 않습니다. API가 잘못된 형식의 JSON을 반환하거나, 인증 헤더를 무시하거나, OpenAPI 계약에서 벗어나더라도 부하 테스트는 훌륭하게 통과할 수 있습니다. 처리량이 정확성을 의미하지는 않습니다.

이는 기능 및 계약 테스트가 채워주는 공백이며, Apidog가 부하 도구를 대체하는 대신 보완하는 지점입니다. Apidog는 부하 생성기가 아닙니다. 저장된 테스트 시나리오를 실행하여 상태 코드, 응답 스키마, 그리고 다단계 흐름 전반의 값들을 단언(assert)하므로, 벤치마크가 볼 수 없는 버그를 잡을 수 있습니다.

두 도구 모두 CI에서 실행하며, 서로 다른 질문에 답합니다. autocannon (또는 wrk)을 사용하여 "부하 하에서 충분히 빠른가?"라는 질문에 답하십시오. Apidog CLI를 사용하여 "올바른가?"라는 질문에 답하십시오. Apidog CLI는 헤드리스(headless)이며 Node가 있는 모든 CI 단계에서 저장된 테스트 시나리오 또는 스위트를 실행합니다:

npm install -g apidog-cli

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,html,junit

-t 플래그는 ID로 저장된 시나리오, 폴더 또는 스위트를 대상으로 하며, -e는 환경을 선택하고, -r은 하나 이상의 리포터(cli, html, json, junit)를 선택하여 파이프라인에서 아카이브할 수 있는 아티팩트를 생성합니다. 전체 안내는 Apidog CLI에서 API 테스트를 실행하는 방법, 복사-붙여넣기 CI/CD 파이프라인, 그리고 GitHub Actions 워크플로우를 참조하십시오.

건전한 파이프라인은 모든 푸시(push)에 대해 기능 및 계약 검사("작동하는가?")를 실행한 다음, 릴리스 전에 부하 테스트("버틸 수 있는가?")를 실행합니다. autocannon은 두 번째 질문에 답하고, Apidog는 첫 번째 질문에 답합니다.

자주 묻는 질문

autocannon은 프로덕션 부하 테스트에 정확한가요?

autocannon은 HTTP/1.1 엔드포인트에 대해 신뢰할 수 있는 처리량 및 지연 시간 수치를 생성하며, -R로 목표 속도를 설정할 때 많은 간단한 도구들이 건너뛰는 협력적 생략(coordinated omission)을 보정합니다. 정확한 결과를 얻으려면 서버와 가까운 머신에서 실행하고 (그렇지 않으면 네트워크 지연 시간이 지배적임) 엔드포인트를 포화시킬 수 있는 충분한 연결을 사용하십시오. 노트북의 개발 서버가 아닌, 프로덕션을 미러링하는 스테이징 환경에 대해 실행하십시오.

autocannon은 HTTP/2 또는 WebSockets를 지원하나요?

아니요. autocannon은 HTTP/1.1을 벤치마킹합니다. HTTP/2 또는 WebSocket 부하 테스트를 위해서는 다른 도구가 필요합니다. 이것이 이 도구를 선택하기 전에 확인해야 할 주요 제약 사항입니다.

몇 개의 연결을 사용해야 하나요?

기본값인 10에서 시작하여 초당 요청 수가 더 이상 증가하지 않고 지연 시간이 증가하기 시작할 때까지 -c를 늘리십시오. 그 변곡점이 대략 서버의 용량입니다. 이를 훨씬 초과하여 부하를 가하는 것은 서버의 한계보다는 부하 생성기의 한계를 측정하는 것입니다.

CI에서 autocannon을 실행할 수 있나요?

예. 프로그래밍 API는 이를 위해 만들어졌습니다: 벤치마크를 실행하고, result.latency.p99 및 result.non2xx를 읽고, 예산이 초과될 때 process.exit(1)을 호출하십시오. 이는 벤치마크를 Node를 사용할 수 있는 모든 CI 단계에 연결할 수 있는 합격/불합격 게이트로 전환합니다.

-a와 -d의 차이점은 무엇인가요?

-d는 지정된 시간(초) 동안 실행됩니다. -a는 지정된 수의 요청이 완료될 때까지 실행된 다음 중지됩니다. 정상 상태 부하 테스트에는 -d를 사용하고, 정확한 요청 수를 보내고 싶을 때는 -a를 사용하십시오.

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요