Api::V1::VideosController#create_upload_credentials (avg 1381ms, max 1386ms)
RCA: Api::V1::VideosController#create_upload_credentials Latency (avg 1381ms)
Overview#
What Happened#
2026-05-27 05:17~05:19 UTC에 us-west-2 리전에서 Api::V1::VideosController#create_upload_credentials 엔드포인트의 응답 시간이 평균 1381ms로 급격히 증가했다. 동일 시간대에 해당 리전의 모든 API 엔드포인트에서 유사한 지연이 발생했으며, 이는 05:15Z에 시작된 rolling deployment(production-us-west-2-20260527t0515z0-650f3601)와 시간적으로 일치한다.
Quick Facts#
| Field | Value |
|---|---|
| resource_name | Api::V1::VideosController#create_upload_credentials |
| avg_duration | 1381ms |
| max_duration | 1386ms |
| db_time | 8-15ms (정상) |
| deploy | production-us-west-2-20260527t0515z0-650f3601 |
| env | production, us-west-2 |
Timeline#
- 05:15:00Z — Rolling deployment 시작 (
650f3601) - 05:16:15Z — 새 호스트
ip-10-1-144-228트래픽 수신 시작 - 05:17:55Z — 첫 번째 고지연
create_upload_credentials요청 감지 (1374ms) - 05:19:30Z — 마지막 고지연 요청 (1381ms)
- ~05:28:00Z — 동일 호스트의 응답 시간 정상화 (health check 6-47ms)
Error Log#
{
"resource_name": "Api::V1::VideosController#create_upload_credentials",
"service": "cupixworks-api",
"occurrences": 2,
"avg_ms": 1381,
"max_ms": 1386,
"sample_trace_id": "3237972821302513401"
}
Impact#
- Service:
cupixworks-api - 발생 횟수: 2 (클러스터 기준), 실제 4건 확인 (Datadog 로그)
- 최초 발생: 2026-05-27T05:17:55.209Z
- 최근 발생: 2026-05-27T05:19:30.986Z
- 영향 범위: us-west-2 리전의 단일 사용자 (chan.lee@cupix.com), 비디오 업로드 credential 발급 지연. 기능 장애 없음 (HTTP 200).
Root Cause Summary#
Rolling deployment 직후 발생한 인프라 레벨 warmup 지연이 원인이다. 05:15Z에 production-us-west-2-20260527t0515z0-650f3601 버전이 배포되면서 새 인스턴스(ip-10-1-144-228)가 트래픽을 받기 시작했고, Ruby 프로세스 warmup, GC 압력, connection pool 초기화 등으로 인해 모든 엔드포인트에서 1000-3600ms의 응답 지연이 발생했다. DB 시간은 8-15ms로 정상이었으며, 지연의 대부분은 application-level 오버헤드에서 발생했다. 약 10분 후 자연 해소되었다.
Technical Analysis#
Code Path#
- Entry point:
app/controllers/concerns/single_resourcable/videos_controller.rb:7 - Authentication:
app/controllers/concerns/verification_controller.rb:15— Cognito auth (캐시됨) - Resource lookup:
app/controllers/concerns/single_resourcable_controller.rb:23— DB query - Model method:
app/models/concerns/storagable/resource.rb:151—upload_credentials - AWS STS call:
app/services/cupix/storage_service.rb:138—get_federation_token(매 요청마다 호출, 캐시 없음)
def create_upload_credentials
render_json 200, @resource.upload_credentials
end
def upload_credentials
check_upload_credentials
self.uploading unless self.uploading?
Cupix::StorageService.upload_credentials(
storage_option: storage_option,
id: id,
bucket_name: storage_option.s3_source_bucket_name,
key: object(upload_revision).key
)
end
def get_credential_token(storage_option: nil, **kwargs)
client = sts_client(storage_option: storage_option)
opts = kwargs
opts[:duration_seconds] ||= 7200
check_required_params(opts, %i[policy name duration_seconds])
begin
if storage_option.bucket_type == 'minio'
opts[:role_arn] = 'arn:xxx:xxx:xxx:xxxx'
opts[:role_session_name] = opts[:name]
opts.delete(:name)
resp = client.assume_role(opts)
else
resp = client.get_federation_token(opts)
end
rescue StandardError => e
raise Cupix::Errors::System.new(code: 'SYS20000', reason: "Can't create temporary token", message: e.message)
else
resp.credentials
end
end
def sts_client(storage_option: nil, **kwargs)
opts = parse_storage_option(storage_option).merge(kwargs)
Aws::STS::Client.new(opts) # timeout 미설정 — SDK 기본값 사용
end
정상 상태에서 이 엔드포인트의 응답 시간은 50-115ms (다른 리전 기준)이다. 이번 케이스에서 DB 시간은 8-15ms로 정상이었으므로, 나머지 ~1350ms의 지연은 Ruby 프로세스 레벨의 오버헤드(warmup)에서 발생했다.
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-api "VideosController#create_upload_credentials" @duration:>1000
From: 2026-05-27T04:17:55Z To: 2026-05-27T05:49:30Z
고지연 요청 4건 확인:
2026-05-27T05:17:57.676Z | 1374.68ms | db:13.81ms | video:662925 | host:ip-10-1-144-228 | version:20260527t0515z0-650f3601
2026-05-27T05:18:39.971Z | 1342.00ms | db:8.29ms | video:662926 | host:ip-10-1-19-190 | version:20260526t0459z0-dd7bd097
2026-05-27T05:19:03.414Z | 1371.22ms | db:15.64ms | video:662927 | host:ip-10-1-80-134 | version:20260526t0452z0-dd7bd097
2026-05-27T05:19:33.743Z | 1381.76ms | db:12.55ms | video:662928 | host:ip-10-1-144-228 | version:20260527t0515z0-650f3601
동일 시간대 다른 엔드포인트에서도 동일 패턴:
service:cupixworks-api region:us-west-2 @duration:>1000
From: 2026-05-27T05:17:00Z To: 2026-05-27T05:20:00Z
ApiController#status (health check): 1230-1730ms
PanosController#index: 1000-2000ms
PointcloudsController#check_uploading: 1200-1800ms
CapturesController#index: 2800-3600ms
다른 리전 (ap-southeast-2, ap-southeast-1)에서는 동일 시간대에 50-115ms로 정상 응답.
warmup 완료 후 (~05:28Z) health check 응답 시간: 6-47ms로 정상화 확인.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | 배포 후 warmup 지연 (Ruby 프로세스 초기화, GC, connection pool) | 배포 시작(05:15Z) 직후 발생, 모든 엔드포인트에서 동일 패턴, ~10분 후 자연 해소, 다른 리전 정상 | — | Confirmed |
| H2 | AWS STS get_federation_token 호출 지연 |
STS 호출은 매 요청마다 발생하며 캐시 없음, timeout 미설정 | DB 시간 8-15ms와 마찬가지로 외부 호출 시간이 분리되지 않음. 다른 엔드포인트(STS 미호출)도 동일 지연 발생 | Rejected |
| H3 | DB 쿼리 지연 (복잡한 permission JOIN) | 다수의 JOIN이 포함된 쿼리 사용 | 로그에 기록된 DB 시간 8-15ms로 정상 | Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
- 이번 건은 배포 warmup으로 인한 일시적 지연으로, 코드 수정이 필요한 버그가 아니다. 즉시 조치 불필요.
단기 개선 (1주 이내) — Elastic Beanstalk 설정 조정#
cupixworks-api는 Elastic Beanstalk으로 배포된다 (cupix-infrastructure/cupix-service/api-eb/main.tf). EB의 기존 설정으로 warmup 지연을 완화할 수 있다:
1. Deployment Policy 변경 (aws:elasticbeanstalk:command:DeploymentPolicy)
- 현재:
Rolling(variabledeployment_policy) - 권장:
Immutable또는TrafficSplittingImmutable: 새 인스턴스 그룹을 먼저 띄우고 health check 통과 후에만 트래픽을 전환. warmup이 완료되지 않은 인스턴스에 트래픽이 가지 않음.TrafficSplitting: 소량의 트래픽만 먼저 보내고 점진적으로 확대. canary 방식으로 warmup 시간 확보.
deployment_policy = "Immutable" # 또는 "TrafficSplitting"
2. Health Check Threshold 조정 (aws:elasticbeanstalk:environment:process:default)
- 현재:
HealthyThresholdCount=3,UnhealthyThresholdCount=2, timeout=5s, interval=10s - 권장:
HealthyThresholdCount=5,HealthCheckInterval=15,HealthCheckTimeout=10 - 이렇게 하면 인스턴스가 충분히 warmup된 후에만 "healthy"로 전환됨 (최소 75초)
healthcheck_healthy_threshold_count = 5
healthcheck_unhealthy_threshold_count = 3
3. DeregistrationDelay 유지 (aws:elasticbeanstalk:environment:process:default)
-
현재: 60초 — rolling 전환 시 기존 연결 완료에 충분
-
STS credential 캐싱 검토 (
app/services/cupix/storage_service.rb:122): 동일 사용자/리소스에 대해get_federation_token결과를 짧은 TTL(예: 5분)로 캐싱하면 정상 상태에서도 응답 시간을 50ms 이상 단축 가능.
장기 개선 (재발 방지)#
- Prewarming hook via .ebextensions:
.ebextensions/container_command에 warmup 스크립트를 추가하여 Puma 프로세스 시작 후 로컬에서 synthetic 요청을 실행. EB의 lifecycle hook 단계에서 warmup을 완료하면 ALB 등록 전에 Ruby 프로세스가 준비됨. - AWS STS Client timeout 명시 설정 (
app/services/cupix/storage_service.rb:17):Aws::STS::Client.new에http_open_timeout,http_read_timeout을 명시적으로 설정하여 외부 호출 지연이 전체 응답 시간에 미치는 영향을 제한.
Monitoring#
create_upload_credentialsP95 latency 알림 (threshold: 500ms)- 배포 직후 리전별 latency spike 모니터링
service:cupixworks-api resource_name:"Api::V1::VideosController#create_upload_credentials" @duration:>500
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial — 배포 warmup으로 인한 일시적 현상이며 자연 해소됨. 코드 버그 아님.
Revision History#
Revision 1 (2026-05-27)#
Feedback: "deployment 설정을 elasticbeanstalk 에서도 가능한지 확인"
분류: 사실 확인 요청 — EB 인프라 설정으로 해결 가능한지 검증 필요
조사 결과:
cupix-infrastructure/cupix-service/api-eb/main.tf확인: cupixworks-api는 Elastic Beanstalk으로 배포됨- EB 모듈(
_cupix-modules/eb-env/)에서deployment_policy,rolling_update_type,healthcheck_*설정 확인 - 현재 설정:
Rollingdeployment,updating_min_in_service=1, health check threshold=3/2 - EB는
Immutable,TrafficSplitting등 warmup 친화적 배포 정책을 지원 .ebextensions/container_command로 prewarming hook 추가 가능
Verdict: 수용
기존 RCA의 Fix Recommendation 섹션을 Elastic Beanstalk 설정 기반으로 구체화했다. EB의 Immutable/TrafficSplitting deployment policy, health check threshold 조정, .ebextensions prewarming hook 등 EB 네이티브 기능으로 warmup 지연을 방지할 수 있음을 확인하고 반영했다.
변경 사항:
- Fix Recommendation "단기 개선" 섹션에 EB 설정 변경 가이드 추가 (deployment_policy, health check threshold)
- "장기 개선"에 .ebextensions prewarming hook 방안 추가
- 코드 참조:
cupix-infrastructure/cupix-service/api-eb/main.tf:169,_cupix-modules/eb-env/variables.tf:188-198