M12 ‐ 병목 지점 분석 및 비용 예측 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki

V1 부하 테스트 및 비용 분석

1. 분석 목적

V1 배포 이후 현재 인프라 환경에서 Backend가 어느 수준의 Traffic까지 SLO를 만족하며 처리할 수 있는지 확인하기 위해 단계별 부하 테스트를 수행하였다.

부하 테스트 결과와 실제 AWS 운영 비용을 기반으로 다음을 확인한다.

  • V1 환경에서 SLO를 만족하는 최대 부하 수준
  • 성능 저하가 급격하게 발생하는 구간
  • 성능 저하 시점의 EC2 및 Database 관련 자원 상태
  • 현재 V1의 실제 AWS 운영 비용
  • V1 구조를 유지하면서 Scale-Up할 경우 발생하는 비용 변화
  • 향후 인프라 구조 개선 시 고려해야 할 사항

이를 통해 현재 V1 구조의 성능 및 비용 측면의 한계를 확인하고 이후 인프라 구조 개선의 근거로 활용한다.


2. V1 환경

V1은 하나의 EC2 Instance에서 서비스의 주요 구성 요소를 함께 실행하는 구조이다.

EC2 (t3.medium)
│
├── Nginx
├── Frontend (Next.js)
├── Backend (Spring Boot)
├── AI Server (FastAPI)
├── Redis
├── MySQL
└── PostgreSQL + pgvector

현재 EC2 Instance의 사양은 다음과 같다.

항목 구성
Instance Type t3.medium
vCPU 2
Memory 4 GiB
Region ap-northeast-2 (Seoul)

Frontend, Backend, AI Server, Redis는 Container로 실행하며 MySQL과 PostgreSQL은 EC2에 직접 설치하여 사용한다.

따라서 하나의 EC2 자원을 여러 Workload가 공유하고 있으며, 특정 서비스의 부하가 증가하더라도 해당 서비스만 독립적으로 확장하기 어려운 구조이다.


3. 부하 테스트 결과

Backend 주요 사용자 흐름을 대상으로 k6를 이용하여 100 → 200 → 250 → 300 RPS 순으로 부하를 증가시켰다.

일반 Backend API의 SLO는 다음과 같다.

지표 SLO
요청 성공률 ≥ 99%
p95 응답시간 ≤ 300ms
p99 응답시간 ≤ 1,000ms

3.1 테스트 결과

목표 RPS 실제 RPS 성공률 평균 응답시간 p95 p99 Dropped Iterations 결과
100 99.94 100% 15.22ms 22.21ms 47.02ms 0 PASS
200 199.97 100% 28.15ms 70.23ms 238.30ms 0 PASS
250 249.72 99.99% 65.52ms 279.81ms 808.24ms 0 PASS
300 279.64 99.99% 439.19ms 1.96s 2.87s 193 FAIL

100 RPS와 200 RPS에서는 지연시간 SLO를 충분한 여유를 두고 충족하였다.

250 RPS에서는 p95 279.81ms, p99 808.24ms로 SLO를 충족했지만, 200 RPS 대비 응답시간이 크게 증가하였다.

특히 gift-recommendations API의 p95는 297.48ms로 SLO 기준인 300ms에 근접하였다.

300 RPS를 목표로 수행한 테스트에서는 실제 약 279.64 RPS가 전달되었으며, p95 1.96s, p99 2.87s로 지연시간 SLO를 초과하였다.

또한 응답시간 증가로 각 VU가 요청 완료를 기다리는 시간이 길어지면서 필요한 VU가 최대 438까지 증가하였고, 193개의 Dropped Iteration이 발생하였다.

따라서 목표한 300 RPS를 완전히 전달하지 못했지만 약 280 RPS 수준에서 이미 지연시간 SLO가 초과되는 것을 확인하였다.


4. 병목 지점 분석

4.1 병목 발생 구간

단계별 부하 테스트에서 p95 응답시간은 다음과 같이 증가하였다.

100 RPS
p95 22.21ms
    │
    ▼
200 RPS
p95 70.23ms
    │
    ▼
250 RPS
p95 279.81ms
    │
    │ 성능 여유 급격히 감소
    ▼
약 280 RPS
p95 1.96s
    │
    ▼
SLO 초과

100 RPS에서 200 RPS까지는 Traffic 증가에도 응답시간 SLO를 충분한 여유를 두고 충족하였다.

반면 200 RPS 이후부터 응답시간 증가 폭이 커졌으며, 250 RPS에서는 p95가 279.81ms로 SLO 기준인 300ms에 근접하였다.

이후 약 280 RPS에서는 p95가 1.96s까지 증가하면서 SLO를 크게 초과하였다.

따라서 이번 테스트에서 SLO 충족이 확인된 최대 부하는 약 250 RPS이다.

다만 250 RPS 역시 p95가 SLO 기준에 근접하기 때문에 안정적인 운영 한계로 보기는 어렵다.

현재 테스트 결과를 기준으로 250~280 RPS 사이에서 성능 여유가 급격하게 감소하는 구간이 존재하는 것으로 판단한다.


4.2 자원 사용량 분석

250 RPS 테스트 당시 주요 시스템 지표는 다음과 같다.

지표 측정 결과 판단
EC2 CPU 최대 약 77.787% 높은 사용률 확인
EC2 Memory 약 51.18% Memory 포화 징후 없음
HikariCP Active 최대 3 Connection Pool 여유
HikariCP Pending 0 Connection 대기 없음
MySQL Threads Connected 최대 11 명확한 포화 징후 없음
MySQL Threads Running 최대 약 2.4 명확한 포화 징후 없음

250 RPS에서 EC2 CPU는 최대 약 77.787%까지 상승하였다.

CPU가 100%에 근접한 상태로 지속되는 현상은 확인되지 않았지만, 최대 사용률이 약 78%까지 상승했기 때문에 CPU의 영향을 완전히 배제할 수는 없다.

반면 Memory는 약 51% 수준으로 측정되어 Memory 부족에 따른 성능 저하 징후는 확인되지 않았다.

HikariCP에서는 Active Connection이 최대 3이었으며 Pending Connection은 발생하지 않았다. 따라서 DB Connection Pool 고갈에 따른 요청 대기는 확인되지 않았다.

MySQL 또한 Threads_connected 최대 11, Threads_running 최대 약 2.4로 측정되어 해당 지표에서는 명확한 포화 현상이 확인되지 않았다.


4.3 병목 분석 결과

부하 테스트를 통해 병목이 나타나는 부하 구간은 확인했지만 정확한 병목 원인까지는 특정하지 못하였다.

250 ~ 280 RPS
성능 저하 발생
      │
      ├── CPU 최대 약 78%
      │    └── 영향 가능성 존재
      │
      ├── Memory 약 51%
      │    └── 포화 징후 없음
      │
      ├── HikariCP Pending 0
      │    └── Connection 대기 없음
      │
      └── MySQL Thread
           └── 명확한 포화 징후 없음
                    │
                    ▼
            정확한 병목 위치 미확인

현재 V1에서 수집한 지표는 EC2 전체 CPU/Memory 및 DB Connection 관련 지표를 중심으로 구성되어 있다.

따라서 다음과 같은 Application Level의 대기 및 처리시간은 확인하지 못하였다.

  • Tomcat Active / Busy Thread
  • JVM Heap 사용량
  • GC 횟수 및 GC Pause
  • Endpoint별 Backend 처리시간
  • DB Query Latency
  • Slow Query
  • Lock Wait
  • Disk / I/O Wait
  • Nginx → Backend Upstream Response Time

따라서 현재 결과만으로 EC2의 Compute Resource 부족을 직접적인 병목 원인으로 판단할 수 없다.

정확한 병목 위치를 확인하기 위해서는 Application Level Metric을 추가하고, 성능 저하가 발생한 250~300 RPS 구간을 세분화하여 추가 테스트할 필요가 있다.


5. V1 비용 분석

5.1 실제 AWS 운영 비용

V1 운영 이후 AWS에서 실제 발생한 비용은 다음과 같다.

2026년 9월 21~30일

서비스 비용
Amazon Elastic Compute Cloud - Compute $11.37
EC2 - Other $1.48
Amazon Virtual Private Cloud $1.17
Amazon Route 53 $0.51
Amazon EC2 Container Registry (ECR) $0.06
Others $36.30
합계 $50.89

2026년 10월 1~4일

서비스 비용
Amazon Elastic Compute Cloud - Compute $5.69
EC2 - Other $0.67
Amazon Virtual Private Cloud $0.56
Amazon Route 53 $0.50
Amazon EC2 Container Registry (ECR) $0.08
Others $0.00
합계 $7.50

다만 위 금액은 각 월의 전체 기간을 동일하게 운영한 결과가 아니다.

V1은 9월 중 배포되어 운영을 시작했기 때문에 9월 비용은 한 달 전체 사용 비용이 아니며, 10월 비용 역시 현재까지의 누적 비용이다.

또한 9월 Others에서 발생한 $36.30은 세부 항목을 추가로 확인할 필요가 있으므로 현재 단계에서는 V1의 지속적인 운영 비용으로 판단하지 않는다.

따라서 실제 청구 내역은 V1 운영 과정에서 발생한 비용을 확인하는 자료로 활용하고, Instance Type별 비용 비교에는 동일한 운영 시간을 가정한 예상 Compute 비용을 사용한다.


5.2 월간 EC2 Compute 비용 환산

실제 비용은 운영 기간이 서로 다르기 때문에 Instance Type별 비용을 직접 비교하기 어렵다.

따라서 V1 구조를 유지하면서 Instance를 변경할 경우의 비용을 비교하기 위해 월 730시간 상시 실행을 기준으로 예상 Compute 비용을 계산한다.

현재 사용 중인 t3.medium의 시간당 Compute 비용을 $0.052로 적용하면 다음과 같다.

$0.052 × 730시간
= $37.96 / month

따라서 현재 V1의 월 예상 EC2 Compute 비용은 약 $37.96이다.

이는 실제로 현재까지 청구된 금액이 아니라 t3.medium을 한 달 동안 상시 실행한다고 가정했을 때의 예상 Compute 비용이다.


5.3 V1 구조에서의 확장 방식

현재 V1은 Backend뿐 아니라 Frontend, AI Server, Redis, MySQL, PostgreSQL이 하나의 EC2에 함께 배치되어 있다.

따라서 Backend Traffic이 증가하더라도 Backend 실행 자원만 독립적으로 확장하기 어렵다.

현재 구조를 유지하면서 Compute Resource를 추가하기 위한 가장 단순한 방법은 EC2 Instance를 Scale-Up하는 것이다.

현재

t3.medium
2 vCPU / 4 GiB
    │
    │ Scale-Up
    ▼
t3.large
2 vCPU / 8 GiB
    │
    │ Scale-Up
    ▼
t3.xlarge
4 vCPU / 16 GiB

5.4 Scale-Up 비용 예측

서울 리전 Linux On-Demand 가격과 월 730시간 실행을 기준으로 예상 Compute 비용을 계산하였다.

Instance vCPU Memory 시간당 비용 월 예상 비용 현재 대비 증가액 현재 대비
t3.medium 2 4 GiB $0.052 $37.96 - 기준
t3.large 2 8 GiB $0.104 $75.92 +$37.96 2배
t3.xlarge 4 16 GiB $0.208 $151.84 +$113.88 4배

연간 Compute 비용으로 환산하면 다음과 같다.

Instance 월 비용 연간 비용 현재 대비 연간 증가액
t3.medium $37.96 $455.52 -
t3.large $75.92 $911.04 +$455.52
t3.xlarge $151.84 $1,822.08 +$1,366.56

V1 구조를 유지하면서 Instance를 Scale-Up하면 Compute 비용은 Instance 크기에 따라 현재의 2배 또는 4배로 증가한다.


5.5 Scale-Up의 비용 대비 효과

t3.medium → t3.large

t3.large는 Memory가 4 GiB에서 8 GiB로 증가하지만 vCPU는 기존 t3.medium과 동일한 2개이다.

t3.medium
2 vCPU / 4 GiB
$37.96 / month

      ↓ 비용 2배

t3.large
2 vCPU / 8 GiB
$75.92 / month

250 RPS 테스트 당시 Memory 사용률은 약 51%였다.

현재 수집한 지표에서는 Memory 포화가 확인되지 않았기 때문에 Memory를 2배로 증가시키는 것이 250~280 RPS 구간에서 발생한 응답 지연을 직접 해결한다고 보기 어렵다.

따라서 현재 관측 결과만을 기준으로 보면 t3.large는 Compute 비용이 2배 증가하지만 이번 테스트에서 확인된 성능 문제에 대한 개선 효과는 불확실하다.

t3.medium → t3.xlarge

t3.xlarge는 vCPU가 2개에서 4개로 증가하고 Memory 역시 4 GiB에서 16 GiB로 증가한다.

t3.medium
2 vCPU / 4 GiB
$37.96 / month

      ↓ 비용 4배

t3.xlarge
4 vCPU / 16 GiB
$151.84 / month

250 RPS 테스트에서 CPU 사용률이 최대 약 78%까지 상승했기 때문에 CPU 자원이 증가하는 t3.xlarge에서는 성능이 개선될 가능성이 있다.

다만 현재 정확한 병목 원인이 확인되지 않았기 때문에 vCPU가 2배 증가한다고 해서 처리 가능한 RPS 역시 2배 증가한다고 판단할 수 없다.

따라서 다음과 같은 계산은 성립하지 않는다.

t3.medium
약 250 RPS에서 SLO 충족

→ vCPU 2배

t3.xlarge
약 500 RPS 처리 가능

실제 병목이 Tomcat Thread, JVM GC, Application Logic, 특정 Query, Lock 또는 I/O 등에서 발생하고 있다면 Instance를 Scale-Up하더라도 성능 개선 폭이 제한적일 수 있다.

즉 t3.xlarge로 변경하면 월 Compute 비용은 현재의 약 4배로 증가하지만, 현재 결과만으로 비용 증가에 비례한 처리량 향상을 보장할 수 없다.


6. V1 구조의 한계

이번 분석에서 확인한 V1의 핵심적인 문제는 단순히 t3.medium의 사양이 부족하다는 것이 아니다.

현재 측정 결과만으로는 정확한 병목이 CPU, Application, Database Query 또는 I/O 중 어디에서 발생하는지 특정하기 어렵다.

또한 V1에서는 주요 Workload가 하나의 EC2에 결합되어 있기 때문에 특정 Workload의 부하가 증가하더라도 해당 Workload만 독립적으로 확장할 수 없다.

예를 들어 Backend의 자원 요구량이 증가할 경우 다음과 같이 전체 EC2를 확장해야 한다.

Backend 자원 부족
        │
        ▼
EC2 전체 Scale-Up
        │
        ├── Frontend
        ├── Backend
        ├── AI Server
        ├── Redis
        ├── MySQL
        └── PostgreSQL

따라서 실제로 자원이 필요한 구성 요소와 관계없이 전체 Instance의 사양과 비용이 함께 증가한다.

V1 구조에서는 다음과 같은 한계가 존재한다.

  1. Workload별 병목을 독립적으로 관측하기 어렵다.
  2. 특정 Workload만 독립적으로 확장하기 어렵다.
  3. Scale-Up 시 전체 EC2의 고정 Compute 비용이 증가한다.
  4. Scale-Up에 따른 비용 증가가 실제 처리량 증가로 동일하게 이어진다고 보장할 수 없다.

7. 분석 결과

V1 부하 테스트를 통해 약 250 RPS까지 Backend API의 SLO를 충족하는 것을 확인하였다.

그러나 250 RPS에서 p95가 279.81ms로 SLO 기준인 300ms에 근접하였으며, 약 280 RPS에서는 p95 1.96s, p99 2.87s로 급격하게 증가하였다.

따라서 250~280 RPS 사이에서 성능 여유가 급격하게 감소하는 구간이 존재하는 것으로 판단한다.

250 RPS 시점의 주요 자원 상태는 다음과 같다.

지표 결과
CPU 최대 약 77.787%
Memory 약 51.18%
HikariCP Active 최대 3
HikariCP Pending 0
MySQL Threads Connected 최대 11
MySQL Threads Running 최대 약 2.4

Memory, HikariCP, MySQL Thread에서는 명확한 포화 징후가 확인되지 않았다.

CPU는 최대 약 78%까지 상승했으므로 영향을 배제할 수 없지만, 현재 수집한 지표만으로 CPU가 직접적인 병목이라고 단정할 수도 없다.

따라서 Tomcat Thread, JVM/GC, Endpoint 처리시간, Query Latency, I/O 등의 Application Level Metric을 추가하여 정확한 병목 위치를 확인할 필요가 있다.

비용 측면에서는 V1 운영 과정에서 실제 AWS 비용이 발생하고 있으나, 9월과 10월의 운영 기간이 서로 다르기 때문에 실제 청구 금액을 Instance Scale-Up 비교에 직접 사용하기는 어렵다.

동일하게 월 730시간 상시 실행한다고 가정할 경우 EC2 Compute 비용은 다음과 같다.

구성 월 예상 Compute 비용 현재 대비
t3.medium $37.96 기준
t3.large $75.92 2배
t3.xlarge $151.84 4배

t3.large는 현재 포화가 확인되지 않은 Memory만 증가하기 때문에 이번 성능 문제에 대한 개선 효과가 불확실하다.

t3.xlarge는 CPU와 Memory가 모두 증가하므로 성능 개선 가능성은 있지만, 정확한 병목 원인이 확인되지 않았기 때문에 비용이 4배 증가한다고 처리량 역시 같은 비율로 증가한다고 볼 수 없다.

결국 V1에서 확인한 핵심적인 한계는 단순히 EC2 사양이 부족하다는 것이 아니라 여러 Workload가 하나의 확장 단위로 결합되어 있다는 점이다.

V1

하나의 EC2
    │
    ├── Frontend
    ├── Backend
    ├── AI Server
    ├── Redis
    ├── MySQL
    └── PostgreSQL
          │
          ▼
특정 Workload의 부하 증가
          │
          ▼
전체 EC2 Scale-Up
          │
          ▼
전체 Compute 비용 증가

따라서 이후 인프라에서는 단순히 더 큰 Instance를 사용하는 것보다 Workload별 자원 사용량과 Traffic 특성을 독립적으로 관측하고, 실제 부하가 증가한 구성 요소만 선택적으로 확장할 수 있는 구조를 검토할 필요가 있다.


8. 추가 확인 사항

현재 테스트를 통해 성능 저하 구간은 확인했지만 정확한 병목 원인은 특정하지 못하였다.

따라서 다음 단계에서는 아래 항목을 추가로 확인한다.

  • Tomcat Active / Busy Thread
  • JVM Heap / GC
  • Endpoint별 처리시간
  • DB Query Latency
  • Slow Query
  • Lock / I/O Wait
  • Nginx Upstream Response Time
  • 250~300 RPS 구간 세분화 테스트

또한 비용 분석에서는 다음 항목을 추가로 확인한다.

  • 2026년 9월 Others $36.30의 세부 비용 항목
  • EC2 - Other 세부 비용
  • V1 월 전체 운영 시 실제 비용
  • 예상 비용과 실제 청구 비용의 차이

이를 통해 성능 병목의 실제 원인을 확인하고, 이후 인프라 구조 변경에 따른 성능 및 비용 개선 효과를 비교한다.