TIL - 20261007

juni·약 24시간 전

TIL

목록 보기
473/474

1007 운영 자동화/AI 워크플로우 심화 (31/N): Capacity Planning, Load Testing, Bottleneck 분석과 Scaling 전략


✅ 1. “서버가 얼마나 버티나요?”는 단순한 CPU 질문이 아니다

서비스의 Capacity를 물으면 흔히:

EC2 CPU가 몇 Core인가?

RAM이 몇 GB인가?

부터 생각한다.

하지만 실제 처리 한계는:

API

DB

Connection Pool

Queue

Worker

Redis

외부 Provider

Network

File I/O

중 가장 먼저 포화되는 지점에서 결정된다.


✅ 2. 전체 시스템 Capacity는 가장 약한 병목이 결정한다

예:

NestJS
1,000 req/s 가능

PostgreSQL
300 req/s 가능

이라면 실제 서비스 Capacity는 1,000이 아니다.

DB가 먼저 포화되므로 실질적으로는:

약 300 req/s 이하

에서 한계가 나타날 수 있다.


✅ 3. Capacity Planning이란?

간단히 말하면:

앞으로 들어올 부하를 현재 시스템이 얼마나 처리할 수 있는지 측정하고, 언제 어떤 자원을 확장해야 하는지 미리 판단하는 것

이다.


✅ 4. Capacity Planning의 질문

최소한 다음을 답할 수 있어야 한다.

현재 평소 Traffic은?

Peak Traffic은?

현재 처리 한계는?

병목은 어디인가?

여유 Capacity는 얼마나 남았는가?

2배 Traffic이 와도 버티는가?

확장 시 무엇을 먼저 늘려야 하는가?

✅ 5. 먼저 Baseline이 필요하다

측정 없이:

서버 충분한 것 같은데?

또는:

RDS부터 키워야 할 것 같은데?

라고 판단하면 안 된다.


✅ 6. Baseline Metric

예:

API RPS

p50 / p95 / p99 Latency

HTTP Error Rate

CPU

Memory

DB Query Latency

DB Connections

Queue Depth

Worker Throughput

Redis Memory

정도다.


✅ 7. 평균만 보면 안 된다

예:

평균 응답시간
100ms

라고 해도:

p95
1.2초

p99
4초

일 수 있다.

사용자 일부는 이미 매우 느린 경험을 하고 있다는 뜻이다.


✅ 8. Peak를 봐야 한다

일 평균:

10 RPS

여도 광고 캠페인이나 사전예약 오픈 때:

200 RPS

까지 올라갈 수 있다.

Capacity는 평균보다 Peak 상황이 중요하다.


✅ 9. Traffic Pattern도 구분한다

예:

일반 상품 조회

검색

주문 접수

관리자 조회

알림 Job

Export

AI 분석

은 모두 Resource 사용 특성이 다르다.


✅ 10. Read-heavy / Write-heavy

예:

Read-heavy

상품 목록

상품 상세

FAQ

검색

Write-heavy

주문 접수

상태 변경

Audit

Webhook 저장

이다.

Scaling 전략도 달라진다.


✅ 11. API마다 비용이 다르다

예:

GET /products/123
DB PK Query 1회

와:

GET /admin/orders
복잡한 Filter
Join
Count
Sort
Pagination

은 같은 Request 1개가 아니다.


✅ 12. 따라서 RPS만으로 Capacity를 말하면 부족하다

예:

100 RPS

라도 모두 상품 조회인 경우와:

100 RPS

모두 복잡한 관리자 검색인 경우는 전혀 다르다.


✅ 13. Endpoint Profile

예:

Product Detail
CPU 낮음
DB 낮음
Cache 가능

Admin Order Search
CPU 중간
DB 높음

Export
Memory 높음
DB 높음
File I/O 높음

AI Run
CPU/GPU/Memory 높음
Long-running

처럼 분류한다.


✅ 14. Bottleneck이란?

시스템 처리량을 제한하는 가장 좁은 부분이다.

예:

CPU 30%

Memory 40%

DB Connection Pool 100%

이면 CPU를 늘려도 별 도움이 없을 수 있다.


✅ 15. 병목을 찾기 전에 Scale하지 않는다

나쁜 대응:

서비스 느림

↓

EC2 사양 2배

이다.

실제 원인이:

Missing Index

라면 비용만 늘고 문제는 거의 그대로다.


✅ 16. Bottleneck 후보

대표적으로:

Application CPU

Application Memory

Event Loop

DB CPU

DB I/O

DB Lock

Connection Pool

Redis

Queue Worker

External API

Network

File I/O

가 있다.


✅ 17. Application CPU 병목

증상 예:

CPU 90~100%

Latency 상승

DB는 여유

Event Loop 지연

이다.


✅ 18. CPU 병목 원인

예:

대량 JSON 변환

이미지 처리

암호화

큰 Excel 생성

복잡 계산

AI 로컬 실행

등이다.


✅ 19. Node.js는 CPU-bound 작업에 특히 주의

NestJS의 주 Event Loop에서 큰 CPU 작업을 실행하면 다른 요청도 같이 느려진다.


✅ 20. CPU-heavy 작업은 Worker로 분리

예:

Excel 생성

대형 Report

AI 분석

등은 Background Worker로 넘긴다.


✅ 21. Memory 병목

증상:

Memory 지속 증가

GC 빈번

Swap

Process OOM

등이다.


✅ 22. Memory Spike와 Leak은 다르다

Spike:

대형 Export 실행
→ Memory 일시 증가
→ 작업 종료 후 감소

Leak:

요청이 계속될수록
Memory가 계속 증가

이다.


✅ 23. Export Memory 문제

예:

100만 Row를
Memory에 전부 로드

↓

Excel 생성

은 위험하다.


✅ 24. Streaming / Chunking

가능하면:

DB Cursor

↓

10,000 Row

↓

File Write

↓

다음 10,000 Row

처럼 처리한다.


✅ 25. DB CPU 병목

증상:

RDS CPU 높음

Query Latency 증가

Application CPU 낮음

이다.


✅ 26. DB 병목이면 먼저 Query를 본다

순서:

Slow Query 확인

EXPLAIN

Index

N+1

Pagination

Select Column

Join

이다.


✅ 27. DB Scale-up은 그 다음이다

Query가 잘못됐는데 DB 사양만 늘리면 문제를 늦출 뿐이다.


✅ 28. Connection Pool 병목

예:

Pool Size
20

Active
20

Waiting
80

이면 새 Request가 Connection을 기다린다.


✅ 29. Pool Size를 무조건 늘리면 안 된다

Application Instance마다:

20 connections

을 갖고 있고 서버를 10대로 늘리면:

200 connections

이 DB로 몰린다.


✅ 30. Horizontal Scaling이 DB를 더 압박할 수 있다

이게 중요한 함정이다.

App 2대 → 10대

로 늘렸는데 DB가 그대로면 전체 Connection 수와 Query량이 증가한다.


✅ 31. Connection Budget

예:

DB max connections
200

Reserved
40

Application Budget
160

이라고 하자.

App 4대면:

40 per instance

보다 낮게 설정해야 한다.


✅ 32. 실제로는 여유를 더 남긴다

Admin Tool, Migration, Monitoring 연결도 필요하기 때문이다.


✅ 33. DB Connection Pool도 Capacity Planning 대상

App Scale 정책과 같이 봐야 한다.


✅ 34. DB Lock 병목

CPU는 낮은데 Query가 느릴 수 있다.

원인:

Long Transaction

동시 Update

Lock Wait

이다.


✅ 35. 이런 경우 서버 사양 확대는 거의 해결책이 아니다

Transaction 구조를 고쳐야 한다.


✅ 36. Query Latency를 종류별로 본다

예:

Order Detail
p95 15ms

Admin Search
p95 700ms

Report
p95 8s

라면 Report/Search가 병목 후보다.


✅ 37. Redis 병목

예:

Cache

Queue

Rate Limiter

를 같은 Redis가 담당하면 한 Resource에 의존성이 몰릴 수 있다.


✅ 38. Redis Memory가 가득 차면

Cache Eviction뿐 아니라 Queue 안정성에 영향이 갈 수 있다.

1004와 연결된다.


✅ 39. Queue Bottleneck

Producer:

500 jobs/min

Consumer:

200 jobs/min

이면 매분:

300 jobs

가 쌓인다.


✅ 40. Worker Throughput

대략:

처리 완료 Job 수
/
시간

으로 본다.


✅ 41. Throughput과 Latency를 같이 본다

Worker가 초당 많이 처리해도 특정 Job이 너무 오래 기다릴 수 있다.

그래서:

Throughput

Queue Depth

Oldest Age

Job Duration

을 같이 본다.


✅ 42. 외부 API 병목

우리 서버는 여유가 있어도:

Kakao

Notion

LLM API

외부 Provider

가 느리면 전체 Workflow가 느려진다.


✅ 43. 외부 Dependency Capacity는 우리가 Scale할 수 없다

그래서:

Rate Limit

Queue

Concurrency

Circuit Breaker

로 보호한다.


✅ 44. Load Testing이란?

실제 또는 가상의 Traffic을 발생시켜:

시스템이 어느 수준부터 느려지고 실패하는지 측정하는 테스트

다.


✅ 45. Load Test의 목적은 최대 TPS 자랑이 아니다

좋은 질문:

언제 p95가 급증하는가?

어느 Resource가 먼저 포화되는가?

Error가 어디서 시작되는가?

Queue는 얼마나 밀리는가?

이다.


✅ 46. Load Test와 Stress Test 구분

Load Test:

예상 Traffic 범위에서
성능 확인

Stress Test:

한계까지 밀어붙여
어디서 무너지는지 확인

이다.


✅ 47. Spike Test

갑작스러운 Traffic 증가를 본다.

예:

10 RPS

↓

1초 만에

200 RPS

이다.

사전예약/광고 오픈 상황에 유용하다.


✅ 48. Soak Test

장시간 일정 부하를 유지한다.

예:

50 RPS

8시간

이다.

Memory Leak이나 Connection Leak을 찾기 좋다.


✅ 49. Load Test 종류

Baseline Test

Load Test

Stress Test

Spike Test

Soak Test

를 목적에 따라 사용한다.


✅ 50. 처음부터 Stress Test까지 할 필요는 없다

현재는:

Baseline

예상 Peak

Peak × 2

정도부터 시작하면 충분하다.


✅ 51. Production에서 무작정 Load Test하지 않는다

실제 고객과 DB를 위험하게 만들 수 있다.


✅ 52. Staging 환경을 사용한다

가능하면:

유사 Schema

더미 데이터

유사 Application Config

로 구성한다.


✅ 53. 단 Staging 사양이 Production과 다르면 절대 Capacity 숫자로 그대로 쓰지 않는다

예:

Staging
1 vCPU

Production
4 vCPU

이면 Test 결과를 직접 비교하기 어렵다.


✅ 54. 상대 변화 분석에 활용

예:

Index 적용 전
p95 1.5s

Index 적용 후
p95 300ms

같은 개선 비교에는 유용하다.


✅ 55. Production Capacity Test가 필요하다면 매우 제한적으로

실제 서비스 영향이 없는:

Read-only Endpoint

저트래픽 시간

Controlled Ramp

에서만 신중하게 수행한다.


✅ 56. Load Test 전 Safety Limit

예:

Error Rate > 5%
→ 중단

DB CPU > 85%
→ 중단

p95 > 3s
→ 중단

같은 Stop Condition을 둔다.


✅ 57. Ramp Up

갑자기:

0 → 1,000 RPS

하지 않는다.


✅ 58. 단계적으로 올린다

예:

10 RPS
2분

25 RPS
2분

50 RPS
2분

100 RPS
2분

이다.


✅ 59. 각 단계에서 안정화 시간을 준다

Metric이 반응하는 시간을 본다.


✅ 60. Endpoint별 Scenario를 만든다

예:

50%
상품 목록

30%
상품 상세

10%
검색

5%
주문

5%
기타

처럼 실제 Traffic과 비슷하게 구성한다.


✅ 61. 단 실제 Traffic 비율 데이터가 없다면 추정값을 사실처럼 쓰지 않는다

먼저 Access Log/Analytics를 본다.


✅ 62. 관리자 Traffic은 별도 시나리오

고객 Traffic과:

관리자 주문 검색

Excel Export

상태 변경

을 같은 Load Pattern으로 보지 않는다.


✅ 63. Read Scenario

예:

GET /products
GET /products/:id
GET /faq

부터 시작한다.


✅ 64. Search Scenario

다양한 Query로 테스트한다.

같은 Query만 반복하면 Cache 효과 때문에 실제보다 좋아 보일 수 있다.


✅ 65. Cache Warm / Cold Test를 분리

Warm

Cache가 채워진 상태

Cold

Cache가 비어 있는 상태

둘 다 확인한다.


✅ 66. Cold Cache가 중요하다

Redis 재시작이나 Cache Version 변경 후 실제로 발생할 수 있다.


✅ 67. Write Scenario

주문 생성은 실제 Side Effect가 있으므로 Test 전용 데이터/환경에서만 한다.


✅ 68. Idempotency도 같이 검증

동일 Request를 여러 번 보내:

중복 주문이 안 생기는가?

확인한다.


✅ 69. Admin List Test

다양한 조합:

상태 Filter

날짜 Filter

검색

정렬

Pagination

을 테스트한다.


✅ 70. 특히 Worst-case Query를 포함

예:

기간 넓음

검색어 있음

정렬 있음

처럼 비용이 큰 조합이다.


✅ 71. Export Load Test

HTTP Response 시간만 보면 안 된다.

Export Request 생성

Queue 대기

Worker 처리

파일 생성

완료

전체 Workflow를 본다.


✅ 72. Export Capacity Metric

예:

jobs/hour

average duration

p95 duration

memory peak

queue age

이다.


✅ 73. Notification Capacity

예:

Provider allowed rate

Worker concurrency

Retry rate

Queue depth

를 본다.


✅ 74. AI Worker Capacity

예:

1 Run 평균 8분

동시 Run 1

이면 시간당 대략:

7~8건 이하

수준일 수 있다.

정확한 수치는 실제 측정해야 한다.


✅ 75. AI 작업은 RPS보다 Run Throughput이 더 적절

예:

runs/hour

이다.


✅ 76. Capacity Unit을 업무에 맞춘다

예:

Web API
requests/sec

Notification
messages/sec

Export
jobs/hour

AI
runs/hour

이다.


✅ 77. 하나의 Capacity 숫자로 시스템 전체를 표현하지 않는다


✅ 78. Saturation Curve

부하를 올릴수록 보통:

낮은 부하
Latency 안정

↓

중간 부하
Latency 조금 증가

↓

포화 근처
Latency 급증

↓

한계 초과
Error 급증

형태가 된다.


✅ 79. Knee Point

Latency가 갑자기 크게 올라가기 시작하는 지점을 찾는다.


✅ 80. 운영 Capacity는 Knee Point보다 아래로 잡는다

예:

200 RPS
포화 시작

운영 상한
140~160 RPS

처럼 여유를 둔다.


✅ 81. Headroom

현재 사용량 대비 남겨둔 Capacity다.

예:

Peak CPU
50%

Available Headroom
약 50%

처럼 단순하게 볼 수 있다.


✅ 82. CPU만으로 Headroom을 판단하지 않는다

DB가 이미 80%라면 전체 Headroom은 작을 수 있다.


✅ 83. Capacity Headroom을 Resource별로 본다

예:

Application CPU
60% 여유

DB CPU
20% 여유

DB Connections
10% 여유

Queue Throughput
40% 여유

이다.


✅ 84. 가장 적은 Headroom이 우선 위험 후보


✅ 85. Peak 대비 2배 여유가 항상 필요한 것은 아니다

업무 특성에 따라 다르다.

사전예약처럼 Spike가 예상되면 더 많은 여유가 필요할 수 있다.


✅ 86. Capacity Forecast

예:

현재:

Peak Orders
500/day

월 증가:

10%

라면 몇 개월 후 예상 Peak를 대략 계산할 수 있다.


✅ 87. Forecast가 정확해야 하는 것은 아니다

목표는:

언제쯤 확장이 필요할 가능성이 있는가?

를 미리 보는 것이다.


✅ 88. Growth Rate가 급격히 바뀌는 Event도 고려

예:

신제품 출시

광고 캠페인

사전예약 오픈

은 과거 평균으로 예측하기 어렵다.


✅ 89. Event Capacity Plan

사전예약 시작 전:

평소 Traffic × 예상 배수

를 기준으로 별도 Test를 수행한다.


✅ 90. 하지만 “10배 올 것 같다”는 추측만으로 과투자하지 않는다

과거 캠페인, 광고 클릭량 등 근거를 사용한다.


✅ 91. Vertical Scaling

한 서버를 더 크게 만드는 방식이다.

예:

2 vCPU / 4GB

↓

4 vCPU / 8GB

이다.


✅ 92. Vertical Scaling 장점

구현 단순

Architecture 변경 적음

운영 쉬움

이다.


✅ 93. 현재 규모에서는 Vertical Scaling이 현실적일 수 있다

트래픽이 아주 크지 않고 단일 서버 구조라면 먼저 사양을 올리는 것이 더 싸고 단순할 수 있다.


✅ 94. 단 무조건 Vertical Scale이 정답은 아니다

문제가:

Query Bug

Lock

External API

라면 서버 사양을 올려도 해결되지 않는다.


✅ 95. Horizontal Scaling

서버 Instance 수를 늘리는 방식이다.

1대

↓

2대

↓

4대

이다.


✅ 96. 장점

Capacity 증가

Instance 장애 격리

Rolling Deployment

가 쉬워진다.


✅ 97. 단점

State 관리가 복잡해진다.

예:

Local Cache

Local Session

Scheduler 중복 실행

Worker 중복 처리

문제가 생긴다.


✅ 98. Horizontal Scaling 전 확인

Session 외부화

Shared Cache 필요 여부

Scheduler Lock

Worker Idempotency

Shared File Storage

를 본다.


✅ 99. Stateless API가 Scale Out에 유리

API Instance가:

Local Disk

Local Session

Local State

에 의존하지 않을수록 좋다.


✅ 100. 파일을 Local Disk에 저장하면

Instance A에서 업로드한 파일을 Instance B가 못 볼 수 있다.

S3 같은 공유 Storage가 더 적합하다.


✅ 101. Session도 마찬가지

서버 Memory에 Session이 있으면:

Request 1
Server A

Request 2
Server B

에서 문제가 생길 수 있다.


✅ 102. JWT 기반이라면 상대적으로 Stateless

하지만 Revocation/Session State가 있다면 별도 고려한다.


✅ 103. Scheduler Horizontal Scaling

Instance가 3대면 Cron도 3번 실행될 수 있다.


✅ 104. Distributed Lock / Leader Election

하나만 실행해야 하는 Scheduler는:

DB Lock

Redis Lock

Lease

등으로 중복을 막는다.


✅ 105. Worker는 오히려 Horizontal Scaling하기 쉽다

Queue에서 각 Worker가 Job을 가져가면 된다.

단:

Atomic Claim

Idempotency

Concurrency

가 필요하다.


✅ 106. Worker Scale Out

예:

Notification Worker
1대 → 3대

로 처리량을 늘릴 수 있다.


✅ 107. 하지만 Provider Rate Limit이 그대로라면 의미가 없다

Worker 3대가 각자 초당 20건을 보내:

60 req/s

가 되면 Provider Limit을 넘을 수 있다.


✅ 108. Global Provider Rate Limit이 필요할 수 있다

여러 Worker가 하나의 공유 Rate Limit을 사용한다.


✅ 109. DB도 Scale 전략이 있다

대표적으로:

Scale Up

Read Replica

Partition

Sharding

등이 있다.


✅ 110. 지금 Sharding부터 생각할 필요는 없다

현재 규모에서 대부분:

Query Optimization

Index

RDS Scale-up

이 먼저다.


✅ 111. Read Replica

Read-heavy 서비스에서 조회 일부를 Replica로 보낼 수 있다.


✅ 112. 하지만 Replication Lag가 있다

Primary:

Order COMPLETED

직후 Replica에서는 아직:

WAITING

일 수 있다.


✅ 113. Strong Read가 필요한 API는 Primary 사용

예:

상태 변경 직후 상세 조회

같은 경우다.


✅ 114. Analytics/Report에는 Replica가 적합할 수 있다

몇 초 지연이 괜찮다면 가능하다.


✅ 115. 현재는 Replica가 필요할 정도인지 먼저 측정

Read Load가 실제 병목일 때 도입한다.


✅ 116. Cache vs Read Replica

Cache:

반복 Read 감소

Read Replica:

Read Query를 다른 DB에 분산

이다.

역할이 다르다.


✅ 117. Cache가 더 단순한 경우도 많다

상품/FAQ처럼 Stale 허용 가능한 데이터는 Cache가 먼저다.


✅ 118. 관리자 검색 같은 Dynamic Query는 Replica가 더 적합할 수도 있다

하지만 현재 트래픽 규모에서 필요한지 측정한다.


✅ 119. Database Scale-up 신호

예:

Query 최적화 완료

Connection 관리 정상

CPU/I/O 지속 포화

Traffic 증가 추세

일 때다.


✅ 120. Application Scale-up 신호

예:

CPU 지속 80%+

Memory 지속 부족

Event Loop Lag

DB는 여유

등이다.


✅ 121. Scale-out 신호

예:

한 Instance 한계 접근

무중단 배포 필요

Availability 요구 증가

Traffic 변동성 큼

등이다.


✅ 122. Worker Scale-out 신호

Queue Age 증가

Job Throughput 부족

Downstream은 여유

이다.


✅ 123. 반대로 Downstream이 병목이면 Worker를 늘리지 않는다

예:

Provider 20 req/s 제한

이면 Worker 20대가 의미 없다.


✅ 124. Bottleneck Decision Tree

간단히:

Latency 상승
↓
App CPU 높음?
→ App 최적화 / Scale

아니오
↓
DB Latency 높음?
→ Query / DB 확인

아니오
↓
Queue Age 높음?
→ Worker 확인

아니오
↓
External API 느림?
→ Provider / Circuit / Rate Limit

처럼 본다.


✅ 125. 한 번에 여러 Resource를 Scale하지 않는다

EC2 2배

RDS 2배

Redis 2배

Worker 3배

를 한꺼번에 하면 어떤 변경이 효과가 있었는지 알 수 없다.


✅ 126. Bottleneck 하나씩 제거

Measure

↓

Change

↓

Measure Again

한다.


✅ 127. 이것이 Capacity Tuning의 기본 루프다


✅ 128. Load Test 결과 예

50 RPS
p95 120ms
DB CPU 25%

100 RPS
p95 190ms
DB CPU 45%

150 RPS
p95 350ms
DB CPU 72%

180 RPS
p95 1.2s
DB CPU 95%

이라면 DB가 병목 후보다.


✅ 129. 이때 Application 서버를 늘리는 것은 오히려 DB를 더 압박할 수 있다

먼저 Slow Query/Index를 본다.


✅ 130. 개선 후 재테스트

예:

Index 추가 후

180 RPS
p95 280ms
DB CPU 60%

가 됐다면 Infrastructure Scale 없이 Capacity가 늘어난 것이다.


✅ 131. 성능 개선은 가장 싼 Scaling일 수 있다

좋은 Query 하나가 EC2/RDS 업그레이드보다 효과가 클 수 있다.


✅ 132. Capacity Planning과 비용

Scale은 비용을 만든다.

따라서:

성능

안정성

비용

세 가지를 같이 본다.


✅ 133. Cost per Request

개념적으로:

월 Infra 비용
/
월 처리 요청 수

를 볼 수 있다.


✅ 134. 하지만 모든 Request 비용이 같지 않다

AI/Export는 일반 GET보다 훨씬 비싸다.

그래서 업무별 Cost를 따로 볼 수 있다.


✅ 135. Cost per Workflow

예:

Export 1건

AI Report 1건

Notification 1건

당 대략 비용을 계산할 수 있다.


✅ 136. 외부 API 비용도 포함

예:

LLM Token

문자/알림 비용

Storage

Data Transfer

등이다.


✅ 137. Capacity를 돈으로 해결하기 전에 낭비를 제거

예:

중복 API 호출

N+1

불필요한 전체 Select

중복 AI Run

Cache 미사용

이다.


✅ 138. Scale Up vs Optimize 판단

예:

Optimization 2주 필요

Server Upgrade 월 +3만원

이고 Traffic이 작은 경우라면 서버 업그레이드가 더 경제적일 수도 있다.


✅ 139. 반대로 구조적 Query 문제가 있으면 계속 비용이 증가한다

Traffic이 늘수록 Scale 비용도 계속 올라간다.


✅ 140. 1인 개발자는 운영 복잡도 비용도 생각해야 한다

예:

Redis Cluster

Read Replica

Auto Scaling

Service Discovery

를 관리하는 시간도 비용이다.


✅ 141. 가장 싼 Infrastructure가 항상 가장 싼 시스템은 아니다

운영 시간이 과도하게 들면 총비용은 오히려 커진다.


✅ 142. 현재 같은 1인 개발 환경에서는 단순함이 중요

가능하면:

한 단계 높은 EC2/RDS

가:

복잡한 Distributed Architecture

보다 나을 수 있다.


✅ 143. 하지만 Single Point of Failure도 고려

단일 서버가 장애 나면 전체 서비스가 멈출 수 있다.


✅ 144. Capacity와 Availability는 다른 문제다

서버 한 대가 충분히 빠르다고:

고가용성

인 것은 아니다.


✅ 145. Scale-out은 Capacity뿐 아니라 Availability에도 도움

서버 2대라면 한 대 장애 시 다른 서버가 처리할 수 있다.


✅ 146. 단 DB가 하나면 여전히 DB가 SPOF일 수 있다

RDS Multi-AZ 같은 별도 Availability 전략이 있다.


✅ 147. 현재 Capacity 문제와 HA 문제를 섞지 않는다

각각 우선순위를 따로 판단한다.


✅ 148. Headroom Policy

예:

정상 Peak에서
CPU 70% 이하

DB Connections 70% 이하

Queue Lag SLO 만족

같은 내부 기준을 둘 수 있다.


✅ 149. 숫자는 실제 환경에 맞춰 조정한다

70%가 절대 규칙은 아니다.


✅ 150. Resource Alert

예:

CPU 80% 이상 10분

Memory 85% 이상

DB Connection 80%

Queue Lag SLO 초과

등을 설정한다.


✅ 151. 순간 Spike 하나로 Scale하지 않는다

지속 시간과 반복성을 본다.


✅ 152. Autoscaling

Metric에 따라 자동으로 Instance 수를 조절할 수 있다.


✅ 153. 대표 Signal

CPU

Request Count

Queue Depth

등이다.


✅ 154. Web API는 CPU 기반 Autoscaling을 쓸 수 있다

하지만 CPU와 Traffic 상관관계가 실제로 있어야 한다.


✅ 155. Worker는 Queue Depth/Age가 더 적합할 수 있다

예:

Queue Depth ↑
→ Worker 증가

이다.


✅ 156. 하지만 다시 Downstream Capacity를 고려

Worker를 늘렸는데 DB/Provider가 먼저 포화되면 안 된다.


✅ 157. Scale-out 최대값

예:

min 1
max 5

처럼 상한을 둔다.


✅ 158. 무한 Autoscaling은 비용과 장애를 키울 수 있다

잘못된 Retry Storm에 Auto Scaling이 반응해 서버를 계속 늘릴 수도 있다.


✅ 159. Autoscaling도 Circuit Breaker가 필요하다고 볼 수 있다

최대 Capacity를 정한다.


✅ 160. Scale Down도 조심한다

Traffic이 잠깐 줄었다고 바로 Instance를 줄이면 다시 늘어날 때 출렁인다.


✅ 161. Cooldown

예:

Scale Up 후
10분 동안 Scale Down 금지

같은 안정화 기간을 둔다.


✅ 162. Hysteresis

1005/1006과 같은 원리다.


✅ 163. 현재는 Autoscaling까지 바로 갈 필요 없다

먼저:

Metric

Load Test

Manual Scaling 기준

을 잡는다.


✅ 164. Manual Capacity Runbook

예:

1. 병목 Metric 확인

2. 최근 Traffic 증가 확인

3. Query Regression 확인

4. Cache 상태 확인

5. Queue 상태 확인

6. Scale 필요 여부 결정

7. 한 단계 Scale

8. 재측정

이다.


✅ 165. Scale 전에 Regression을 확인

어제까지 정상인데 오늘 갑자기 느려졌다면:

Traffic 성장

보다:

새 배포 Bug

일 가능성도 있다.


✅ 166. Deployment Marker

Metric Dashboard에 Release 시점을 표시하면 좋다.

09:00 release v123

09:05 DB latency 상승

같은 상관관계를 볼 수 있다.


✅ 167. Query Regression

신규 기능이:

Orders 조회마다
추가 Query 20개

를 만들었을 수 있다.


✅ 168. 이때 Scale보다 Rollback/Optimization이 우선


✅ 169. Capacity Regression Test

중요 API의 성능이 배포마다 악화되지 않는지 확인한다.


✅ 170. 예

Admin Order List
p95 baseline 300ms

신규 변경
p95 900ms

이면 Review한다.


✅ 171. CI에서 완전한 Load Test를 매번 돌릴 필요는 없다

시간과 비용이 크다.


✅ 172. 짧은 Performance Smoke Test

예:

대표 Query 100회

평균/p95 비교

정도로 Regression을 잡을 수 있다.


✅ 173. 정기적인 Full Load Test

예:

큰 Release 전

사전예약 전

Infra 변경 전

에 수행한다.


✅ 174. Capacity Event Calendar

특히 Traffic 이벤트가 있다면:

아이폰 사전예약

갤럭시 출시

대규모 광고

전 미리 Capacity Test를 할 수 있다.


✅ 175. 이벤트 전 Checklist

Cache Warm?

DB Index 확인?

Rate Limit 확인?

Queue Worker 확인?

Provider Limit 확인?

Kill Switch 준비?

Monitoring 준비?

이다.


✅ 176. Traffic Replay

실제 과거 Access Log를 기반으로 유사 Traffic을 재현할 수 있다.


✅ 177. 단 개인정보/실제 Payload를 그대로 재사용하지 않는다

익명화하거나 Pattern만 추출한다.


✅ 178. Synthetic Scenario가 더 단순할 수 있다

대표 Endpoint 비율로 생성한다.


✅ 179. Load Test Tool

예:

k6

Artillery

JMeter

같은 도구를 사용할 수 있다.

현재 Node/JS 환경이라면 k6나 Artillery가 접근하기 쉬울 수 있다.


✅ 180. 도구보다 Scenario가 중요하다

좋은 Tool을 써도:

GET /
만 1000번

이면 실제 Capacity를 제대로 알기 어렵다.


✅ 181. Test Data Size도 중요하다

Orders 100건 DB와:

Orders 1,000,000건

DB의 Query 성능은 다르다.


✅ 182. 데이터 Volume을 현실적으로 맞춘다

적어도:

현재 Production 규모

앞으로 예상 규모

에 가까운 더미 데이터로 테스트한다.


✅ 183. 개인정보 Production Dump를 그대로 쓰지 않는다

가능하면 생성형 더미 데이터를 사용한다.


✅ 184. Index Cardinality도 유사하게

모든 Status가 동일한 더미 데이터면 실제 Query Planner 행동과 다를 수 있다.


✅ 185. 데이터 분포

예:

WAITING 10%

COMPLETED 70%

CANCELLED 20%

처럼 현실적인 분포를 재현한다.


✅ 186. Search Data도 다양하게

동일 이름/번호 패턴만 넣지 않는다.


✅ 187. Load Test 중 Logging도 실제와 비슷하게

Debug Logging을 켜두면 Production보다 더 느릴 수 있다.


✅ 188. 반대로 Logging을 완전히 끄면 실제 비용을 놓칠 수 있다

Staging 설정을 Production과 최대한 맞춘다.


✅ 189. Compression/TLS도 영향을 줄 수 있다

정밀 Capacity 숫자가 필요하면 Network 경로도 유사하게 구성한다.


✅ 190. 하지만 현재는 지나친 정밀 모델링보다 병목 발견이 우선


✅ 191. Capacity Dashboard

예:

Traffic

RPS
Peak RPS

Latency
p50/p95/p99

Application
CPU
Memory

Database
CPU
Connections
Query Latency

Queue
Depth
Oldest Age
Throughput

정도다.


✅ 192. Capacity Scorecard

주간으로:

Current Peak

Tested Capacity

Headroom

Top Bottleneck

Next Action

을 정리할 수 있다.


✅ 193. 예

Peak
40 RPS

Tested Stable
150 RPS

Headroom
약 3.7x

Primary Bottleneck
Admin Search DB Query

같은 식이다.


✅ 194. 단 Load Test와 실제 Production 차이를 명시한다

“150 RPS까지 보장”이 아니라:

Staging Test 기준
150 RPS에서 SLO 만족

처럼 표현한다.


✅ 195. Capacity 기록은 포트폴리오에도 가치가 있다

단순:

AWS 배포했습니다.

보다:

Load Test를 통해 DB 병목을 식별하고
Index 개선 후 p95와 처리량을 개선했다.

가 훨씬 강한 실무 경험이 된다.


✅ 196. 성능 개선 Before / After

예:

Before
Admin List p95 1.4s

After
420ms

처럼 근거를 남긴다.


✅ 197. 단 테스트 조건도 함께 기록

예:

Dataset
500k rows

Concurrency
50

Environment
Staging

을 같이 남긴다.


✅ 198. 숫자만 떼어내 과장하지 않는다


✅ 199. Load Test Result 모델

예:

interface LoadTestRun {
  id: string;

  scenario: string;

  environment: string;

  startedAt: Date;

  peakRps?: number;

  p95?: number;

  errorRate?: number;

  bottleneck?: string;
}

정도로 기록할 수 있다.


✅ 200. 꼭 DB Table로 만들 필요는 없다

Markdown Report로 저장해도 충분할 수 있다.


✅ 201. /docs/performance

예:

/docs/performance/
2026-10-preorder-load-test.md

처럼 기록한다.


✅ 202. Report 구조

# 목적

# 환경

# Dataset

# Scenario

# Traffic

# Result

# Bottleneck

# Improvement

# Retest

# Capacity Recommendation

이다.


✅ 203. AI를 Capacity 분석에 활용

AI가 Metric/Load Test 결과를 받아:

Latency 증가 지점

DB CPU 상관관계

Queue 병목

Regression

을 요약할 수 있다.


✅ 204. 예

입력:

RPS
50 → 100 → 150

p95
120 → 170 → 850

DB CPU
30 → 55 → 94

AI가:

150 RPS 부근에서 DB가 주요 병목 후보

라고 분석할 수 있다.


✅ 205. 하지만 AI가 Metric 없이 병목을 단정하면 안 된다

코드만 보고:

RDS를 Scale Up해야 합니다.

라고 결정하지 않는다.


✅ 206. AI 역할

적합:

Metric 요약

상관관계 후보

Slow Query 후보

Test Scenario 생성

Before/After Report

이다.


✅ 207. AI가 바로 Infra Scale 권한을 갖게 하지 않는다

AWS Instance Type 변경은 비용과 Availability에 영향을 준다.

Human Approval이 적합하다.


✅ 208. Scaling Recommendation

예:

Recommendation
Query Optimization First

Reason
DB CPU rises with admin search traffic

Scale-up not yet required

처럼 근거를 남긴다.


✅ 209. Scaling Decision Matrix

상황우선 대응
App CPU 포화코드 최적화 / App Scale
DB CPU 포화Query/Index → DB Scale
DB Connection 포화Pool/Query 확인 → Scale
Queue Lag 증가Worker/Downstream 확인
External API 지연Rate Limit/Circuit/Queue
Memory LeakLeak 수정
Cache Miss StormStampede 대응

✅ 210. Queue Scale Decision

Queue Age 증가

라고 바로 Worker를 늘리지 않는다.


✅ 211. 먼저 Worker Job Duration을 본다

평균 Job이 갑자기:

2초 → 20초

가 됐다면 외부 Provider가 느려진 것일 수 있다.


✅ 212. Provider 병목에서 Worker를 늘리면

동시 요청이 더 늘어 Provider 장애를 악화시킬 수 있다.


✅ 213. Capacity와 Backpressure가 연결된다

1005의:

max concurrency

queue backlog

rate limit

은 Capacity를 실제 운영에서 지키는 장치다.


✅ 214. 테스트에서 찾은 Safe Capacity를 정책에 반영

예:

Worker 안정 처리
20 concurrent

라면:

maxConcurrency = 20

등으로 제한한다.


✅ 215. Capacity는 문서 숫자로만 끝내지 않는다

실제 Guardrail에 반영한다.


✅ 216. Rate Limit도 Load Test 근거로 조정

예:

150 RPS까지 안정

Rate Limit
120 RPS

처럼 Safety Margin을 둔다.


✅ 217. 단 Global RPS Limit 하나만으로 충분하지 않을 수 있다

무거운 Endpoint별 Limit도 필요하다.


✅ 218. Resource Budget

예:

Interactive API
DB Connection 70%

Background Worker
30%

처럼 Resource를 나눌 수도 있다.


✅ 219. Worker가 DB Connection을 모두 써버리지 않게 한다

API/Worker별 Pool 또는 Concurrency를 제한할 수 있다.


✅ 220. Bulkhead와 Capacity Planning 연결

0924의 Bulkhead가 실제 Capacity Allocation이 된다.


✅ 221. 예

Notification
10 concurrency

Export
2

AI
1

으로 각각 Resource를 격리한다.


✅ 222. Export 폭주가 Notification을 밀어내지 않게 한다


✅ 223. Peak Event 모드

사전예약 오픈처럼 예상되는 Peak 상황에서는:

AI OFF

Heavy Report OFF

Worker 조정

Cache Warm

등을 미리 적용할 수도 있다.


✅ 224. Event Mode

예:

NORMAL

PEAK_EVENT

Config를 둘 수 있다.


✅ 225. 하지만 자동으로 모든 걸 바꾸는 복잡한 시스템은 필요 없다

Runbook 형태로 준비해도 충분하다.


✅ 226. Peak Event Runbook

1. DB 상태 확인

2. Cache Warm

3. Low Priority Job Pause

4. Export 제한

5. Notification Worker 확인

6. Dashboard Monitoring

7. Event 종료 후 정상화

이다.


✅ 227. Pre-scaling

예상 Traffic 직전에 App Server를 미리 한 단계 늘리는 전략도 있다.


✅ 228. Auto Scaling보다 단순할 수 있다

이벤트 시간이 명확하면:

오픈 30분 전 Scale Up

종료 후 Scale Down

같은 방식이다.


✅ 229. 단 종료 시간을 너무 빨리 잡지 않는다

Backlog가 남아 있을 수 있다.

Queue 정상화 후 Scale Down한다.


✅ 230. Scaling 후 Health Check

1006과 연결된다.

신규 Instance가:

READY

상태가 된 뒤 Traffic을 보낸다.


✅ 231. Scale-out 과정 자체도 부하를 만들 수 있다

Cold Cache 때문에 DB Traffic이 증가할 수 있다.


✅ 232. 신규 Instance Cache Warm-up

필요한 Hot Data만 미리 준비할 수 있다.


✅ 233. 하지만 모든 Instance가 동시에 Warm-up하면 DB를 때릴 수 있다

Jitter/순차 시작을 고려한다.


✅ 234. Scale-in도 Graceful Drain

Instance를 줄이기 전에:

Readiness OFF

↓

Drain

↓

Terminate

한다.

1006과 연결된다.


✅ 235. Worker Scale-in도 마찬가지

Active Job을 안전하게 넘긴다.


✅ 236. Capacity Incident

예:

광고 Traffic 급증

↓

DB Connection Pool 포화

↓

API p95 4초

↓

Client Retry

↓

Traffic 더 증가

이다.


✅ 237. 이 경우 Incident 대응

1. Retry Storm 확인

2. Low Priority 기능 제한

3. Rate Limit

4. Heavy Query 차단

5. 필요 시 Scale

6. Queue/DB 안정화

순이다.


✅ 238. 무조건 Scale부터 하지 않는다

원인이:

Retry Loop

라면 Scale이 공격 Traffic을 더 많이 받아주는 결과가 될 수도 있다.


✅ 239. Capacity Postmortem

질문:

어떤 Resource가 먼저 포화됐나?

사전에 알 수 있었나?

Alert가 있었나?

Load Test가 현실적이었나?

Headroom은 충분했나?

Scale보다 Optimization이 나았나?

이다.


✅ 240. Capacity 관련 Error Budget

SLO 위반이 반복되면:

신기능보다 성능 개선 우선

으로 전환할 수 있다.


✅ 241. 0922 Error Budget와 연결된다

Capacity 부족은 단순 Infra 이슈가 아니라 Product Delivery 우선순위에도 영향을 준다.


✅ 242. Capacity Review 주기

트래픽이 작은 서비스라면 매주 볼 필요는 없다.

예:

월 1회

큰 Release 전

마케팅 Event 전

정도로 충분할 수 있다.


✅ 243. 신규 기능이 Resource 사용을 크게 바꾸면 즉시 Review

예:

AI 분석

대형 Export

실시간 상태 조회

복잡 Search

등이다.


✅ 244. Capacity Review 문서

Current Load

Peak Load

SLO

Headroom

Top Bottleneck

Growth Trend

Recommended Action

정도로 유지한다.


✅ 245. 현재 프로젝트에서 가장 먼저 할 일

1단계

API p95/p99

DB Query Latency

DB Connection

Queue Depth/Age

Metric 확보.


✅ 246. 2단계

대표 Endpoint 선정:

상품 목록

상품 상세

관리자 주문 목록

검색

이다.


✅ 247. 3단계

Staging Baseline Load Test.


✅ 248. 4단계

병목 1개 수정.

예:

Index

N+1

Pagination

Cache

이다.


✅ 249. 5단계

같은 Scenario 재테스트.

Before/After 비교.


✅ 250. 6단계

Export/Notification/AI Worker Capacity를 별도로 측정.


✅ 251. 7단계

사전예약 같은 Peak Event 전:

Spike Test

Peak Runbook

을 준비한다.


✅ 252. 현재 당장 과한 것

Kubernetes HPA

Multi-region Autoscaling

Database Sharding

복잡한 Read Replica Routing

Service Mesh Capacity Control

자동 AI Infra Scaling

까지는 필요 없다.


✅ 253. 현재 현실적인 확장 순서

1. Query 개선

2. Cache

3. Worker Concurrency 조정

4. Vertical Scale

5. API/Worker Process 분리

6. Horizontal Scale

7. Read Replica 등

순서로 보는 것이 현실적이다.


✅ 254. 단 순서는 절대 규칙이 아니다

실제 Bottleneck에 따라 바뀐다.


✅ 255. Capacity Planning 핵심 원칙

측정 없는 Scaling 금지

병목 없는 Optimization 금지

한 번에 하나씩 변경

변경 후 재측정

이다.


✅ 256. Codex 분석 프롬프트

현재 React + NestJS + Prisma + PostgreSQL + AWS 프로젝트를
Capacity Planning 관점에서 분석해줘.

코드를 바로 수정하지 말고
현재 Architecture와 병목 후보를 먼저 파악한다.

목표는 대규모 분산 시스템을 만드는 것이 아니라,

- 현재 어디가 병목이 될 가능성이 있는지
- 어떤 Metric이 부족한지
- Load Test를 어디부터 해야 하는지
- 언제 Vertical / Horizontal Scaling이 필요한지

를 현실적으로 판단하는 것이다.

다음 영역을 검토한다.

1. NestJS API
2. Prisma Query
3. PostgreSQL Connection Pool
4. 관리자 Order Search
5. Product Read
6. Search
7. Export Worker
8. Notification Worker
9. Scheduler
10. AI / Local LLM Worker
11. Redis / Queue가 있다면 해당 Resource
12. S3 / CloudFront

각 영역마다 다음 형식으로 작성한다.

## Component

## Resource Characteristic

- CPU-bound
- Memory-bound
- DB-bound
- I/O-bound
- External API-bound

복수 가능.

## 현재 병목 후보

실제 코드에서 확인되는 내용만 작성한다.

## 필요한 Metric

## Scale 전에 해야 할 Optimization

## Scale 전략

- No Action
- Optimize
- Vertical Scale
- Horizontal Scale
- Worker Scale
- DB Scale

## Priority

P0 / P1 / P2

특히 다음을 찾아줘.

- N+1 Query
- Missing Pagination
- 과도한 include/select
- 긴 Transaction
- Connection Pool 위험
- 대량 Memory Load
- CPU-heavy 작업이 API Process에 있는지
- Background Job으로 보내야 할 작업
- Worker Concurrency가 명시되어 있는지
- External Provider Limit보다 Worker 처리량이 큰지
- Local State 때문에 Horizontal Scale이 어려운지

실제 Traffic Metric이 없으면
몇 RPS까지 버틸 수 있다고 추정하지 않는다.

마지막에는
현재 구조에서 가장 ROI가 높은
Capacity 개선 5개만 우선순위로 정리해줘.

✅ 257. Load Test 설계용 Codex 프롬프트

현재 프로젝트를 위한
Staging Load Test Plan을 작성해줘.

Production 실제 고객 데이터는 사용하지 않는다.

목표는 최대 TPS를 자랑하는 것이 아니라
Latency/Error/Saturation이 급격히 증가하는 지점을 찾는 것이다.

우선 Test 대상:

1. Product List
2. Product Detail
3. Search
4. Admin Order List
5. Order Detail
6. Export Request

각 Scenario마다:

## 목적

## Test Data 조건

## Request Pattern

## Ramp Up

예:
낮은 부하
→ 예상 Peak
→ Peak의 1.5~2배

정확한 RPS는 실제 Baseline을 본 뒤 결정한다.

## 관찰 Metric

- RPS
- p50
- p95
- p99
- error rate
- CPU
- memory
- DB CPU
- DB connections
- query latency
- queue depth
- queue oldest age

## Stop Condition

예:
- error rate 급증
- p95 SLO 초과
- DB Connection Pool 포화
- CPU 장시간 90% 이상
- Health 이상

## 예상 병목 후보

## Test 후 확인사항

Cache 대상 Endpoint는
Warm Cache / Cold Cache Scenario를 나눈다.

Admin Search는
단일 Query만 반복하지 않고
다양한 Filter/Search/Sort 조건을 사용한다.

Write API 테스트는
Test DB와 더미 데이터만 사용한다.

✅ 258. Worker Capacity Test 프롬프트

현재 Queue / Worker를 대상으로
Capacity Test Plan을 작성해줘.

대상:

- Notification
- Export
- Webhook
- Workflow
- AI Task

각 Worker에 대해:

## Capacity Unit

예:
messages/sec
jobs/min
runs/hour

## Current Concurrency

## Job Duration 측정 방법

## Downstream Dependency

## External Rate Limit

## DB 사용량

## Queue Lag SLO

## Load Test 방식

## Scale-out 가능 여부

## Scale-out 시 위험

특히 다음을 확인한다.

1. Worker를 늘리면 DB Connection이 얼마나 늘어나는지
2. External Provider Rate Limit을 넘지 않는지
3. Queue Depth 감소 속도
4. Oldest Job Age
5. Retry Storm 발생 여부
6. Controlled Drain이 가능한지
7. Worker 종료 후 Resume 가능한지

결과에서
'Worker를 늘리면 해결되는 병목'과
'Worker를 늘리면 오히려 악화되는 병목'을
분리해서 설명해줘.

✅ 259. Capacity Report 템플릿

# Capacity Review

## 1. 환경

Application
DB
Queue
Cache
Worker

## 2. Current Production Load

Average RPS

Peak RPS

Peak Orders

Queue Throughput

## 3. Current SLO

Availability

p95 Latency

Queue Lag

## 4. Load Test

Scenario

Traffic

Duration

Dataset

## 5. Result

p50

p95

p99

Error Rate

CPU

Memory

DB CPU

Connections

## 6. Saturation Point

## 7. Primary Bottleneck

## 8. Secondary Bottleneck

## 9. Improvement

## 10. Retest Result

## 11. Current Safe Capacity

## 12. Headroom

## 13. Growth Risk

## 14. Recommended Action

Optimize / Scale / No Action

## 15. Next Review

✅ 260. Scaling Runbook

# Capacity Scaling Runbook

## 1. 증상 확인

- Traffic 증가?
- Latency 증가?
- Error 증가?
- Queue Lag 증가?

## 2. 최근 변경 확인

- Release
- Migration
- Feature Flag
- Traffic Campaign

## 3. 병목 확인

- Application CPU
- Memory
- DB CPU
- DB Connections
- Slow Query
- Queue
- External Provider

## 4. Regression 여부

최근 배포 이후 발생했다면
Scale보다 Rollback/Hotfix 우선 검토.

## 5. Optimization 가능 여부

- Index
- Query
- Cache
- Pagination
- Concurrency

## 6. Scale 결정

Application / DB / Worker 중
실제 병목 Resource만 조정.

## 7. 한 단계 변경

한 번에 여러 Component를 확대하지 않는다.

## 8. Health 확인

Readiness

Error Rate

Latency

## 9. 재측정

개선됐는지 확인.

## 10. 기록

변경 이유와 Before/After Metric 기록.

✅ 261. 실무 체크리스트

Baseline

  • 평균 RPS를 알고 있는가?
  • Peak RPS를 알고 있는가?
  • p50/p95/p99를 보고 있는가?
  • Error Rate를 보고 있는가?
  • Traffic Pattern을 Endpoint별로 구분하는가?

Application

  • CPU를 보고 있는가?
  • Memory를 보고 있는가?
  • CPU-heavy 작업이 API Thread를 막지 않는가?
  • Memory Leak 여부를 확인하는가?
  • 대형 Export를 Streaming/Chunking하는가?

Database

  • Slow Query를 확인하는가?
  • EXPLAIN을 사용하는가?
  • Connection Pool 사용량을 보는가?
  • Long Transaction이 없는가?
  • Scale 전에 Query/Index를 먼저 검토하는가?

Queue / Worker

  • Queue Depth를 보는가?
  • Oldest Job Age를 보는가?
  • Throughput을 측정하는가?
  • Job Duration을 측정하는가?
  • Downstream이 병목인데 Worker만 늘리지 않는가?

Load Test

  • Production에서 무작정 실행하지 않는가?
  • Ramp-up 방식인가?
  • Stop Condition이 있는가?
  • 현실적인 Dataset을 사용하는가?
  • Cache Warm/Cold를 구분하는가?
  • Worst-case Query를 포함하는가?

Scaling

  • 병목 Resource를 확인한 뒤 Scale하는가?
  • Vertical Scale이 더 단순한지 검토하는가?
  • Horizontal Scale 전 Stateless 여부를 확인하는가?
  • Scheduler 중복 실행을 방지하는가?
  • Worker Scale-out 시 Provider Limit을 확인하는가?

Cost

  • Scale 비용을 확인하는가?
  • 운영 복잡도 비용도 고려하는가?
  • Optimization이 더 싼지 비교하는가?
  • 사용하지 않는 Infra를 추가하지 않는가?

Event Traffic

  • 사전예약/광고 같은 Spike Event를 고려하는가?
  • 이벤트 전 Load Test를 하는가?
  • Low Priority 기능을 미리 줄일 수 있는가?
  • Cache/Worker/Rate Limit을 점검하는가?

Reliability

  • Scale-out된 Instance가 READY 후 Traffic을 받는가?
  • Scale-in 시 Graceful Drain하는가?
  • Queue Backlog를 Controlled Drain하는가?
  • Retry Storm이 Capacity를 잠식하지 않는가?

AI

  • AI Run을 일반 RPS와 구분하는가?
  • runs/hour 기준으로 Capacity를 보는가?
  • Local LLM 동시 Run 수를 제한하는가?
  • AI 분석 때문에 Web API가 느려지지 않는가?

📌 요약

1005에서는:

너무 많은 요청이 들어왔을 때
어떻게 제한하고 격리할 것인가

를 다뤘다.

1006에서는:

현재 Instance가
일을 받을 준비가 되어 있는가

를 다뤘다.

1007에서는 그보다 한 단계 앞선 질문인:

그럼 우리 시스템은
실제로 어느 정도까지 처리할 수 있는가?

를 다뤘다.

가장 중요한 첫 번째 원칙은:

Capacity
≠
서버 CPU 사양

이다.

실제 Capacity는:

Application

DB

Connection Pool

Queue

Worker

Redis

External Provider

중 가장 먼저 포화되는 곳에서 결정된다.

따라서 성능 문제가 생겼다고:

EC2 Upgrade

부터 하면 안 된다.

먼저:

Measure
↓
Find Bottleneck
↓
Optimize
↓
Measure Again

순서로 간다.

특히 DB 병목에서는:

Slow Query

Index

N+1

Pagination

Long Transaction

을 먼저 확인한다.

좋은 Query 하나가 Infrastructure Upgrade보다 더 큰 Capacity 증가를 만들 수도 있다.

Load Test 역시:

최대 TPS 기록

이 목적이 아니다.

찾아야 하는 것은:

어느 부하에서

Latency가 급격히 상승하고

Error가 증가하며

어떤 Resource가 먼저 포화되는가

이다.

그래서:

10 RPS
↓
25
↓
50
↓
100

처럼 점진적으로 Ramp-up하면서:

p95/p99

Error Rate

CPU

Memory

DB Connections

Queue Lag

을 같이 본다.

Capacity가 부족하다고 판단됐을 때도 Scale 방법을 구분한다.

Vertical Scaling
=
한 서버를 크게

Horizontal Scaling
=
서버 수를 늘림

이다.

현재처럼 비교적 단순한 구조에서는:

Query Optimization
↓
Cache
↓
Worker Tuning
↓
Vertical Scale

이 먼저일 수 있다.

Horizontal Scale은 그 이후:

Stateless API

Shared Storage

Scheduler 중복 방지

Worker Idempotency

같은 준비가 필요하다.

또 App Instance를 많이 늘린다고 항상 좋아지는 것도 아니다.

App 10대

↓

DB Connection 10배

↓

DB 포화

가 될 수 있기 때문이다.

따라서:

App Capacity

DB Capacity

Worker Capacity

Provider Capacity

를 따로 보면서 전체 시스템을 맞춰야 한다.

특히 Worker에서는:

Queue가 밀린다
→ Worker 추가

로 바로 결론내리지 않는다.

원인이:

외부 Provider 지연

이라면 Worker 추가가 오히려 장애를 악화시킬 수 있다.

현재 프로젝트에서 가장 현실적인 접근은:

1. p95/p99 확보

2. DB Query Latency 확보

3. Queue Depth/Age 확보

4. 대표 Endpoint Load Test

5. 병목 한 개 수정

6. 동일 Scenario 재테스트

7. Before/After 기록

이다.

사전예약이나 대규모 광고처럼 Traffic Spike가 예상된다면:

Peak Event 전
Load Test
↓
Cache 확인
↓
Worker 확인
↓
Low Priority 기능 제한 준비
↓
필요하면 Pre-scale

하면 된다.

그리고 Scale은 성능 문제만이 아니라 비용 문제이기도 하다.

Infra 비용

개발 시간

운영 복잡도

를 모두 봐야 한다.

1인 개발 환경에서는:

복잡한 분산 Architecture로 월 2만원 아끼기

보다:

조금 더 큰 서버를 쓰고
운영 구조를 단순하게 유지

하는 것이 더 경제적인 경우도 충분히 있다.

전체 흐름을 연결하면:

Traffic
↓
Measure
↓
Load Test
↓
Saturation
↓
Bottleneck
↓
Optimize
↓
Retest
↓
Headroom 계산
↓
Scale 필요 여부 결정
↓
Guardrail 적용
↓
Observe

가 된다.

결국 Capacity Planning의 핵심은

“서버를 얼마나 크게 만들 것인가”가 아니라, 현재 시스템의 실제 한계와 병목을 숫자로 확인하고, 가장 작은 비용과 복잡도로 그 병목 하나를 제거한 뒤 다시 측정하는 것

이다.

0개의 댓글