ES /docs

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#

  1. 05:15:00Z — Rolling deployment 시작 (650f3601)
  2. 05:16:15Z — 새 호스트 ip-10-1-144-228 트래픽 수신 시작
  3. 05:17:55Z — 첫 번째 고지연 create_upload_credentials 요청 감지 (1374ms)
  4. 05:19:30Z — 마지막 고지연 요청 (1381ms)
  5. ~05:28:00Z — 동일 호스트의 응답 시간 정상화 (health check 6-47ms)

Error Log#

Datadog Logs

text
{
  "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:151upload_credentials
  • AWS STS call: app/services/cupix/storage_service.rb:138get_federation_token (매 요청마다 호출, 캐시 없음)
app/controllers/concerns/single_resourcable/videos_controller.rb:7-9ruby
def create_upload_credentials
  render_json 200, @resource.upload_credentials
end
app/models/concerns/storagable/resource.rb:151-161ruby
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
app/services/cupix/storage_service.rb:122-145ruby
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
app/services/cupix/storage_service.rb:14-18ruby
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 쿼리:

text
service:cupixworks-api "VideosController#create_upload_credentials" @duration:>1000
From: 2026-05-27T04:17:55Z To: 2026-05-27T05:49:30Z

고지연 요청 4건 확인:

text
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

동일 시간대 다른 엔드포인트에서도 동일 패턴:

text
service:cupixworks-api region:us-west-2 @duration:>1000
From: 2026-05-27T05:17:00Z To: 2026-05-27T05:20:00Z
text
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 (variable deployment_policy)
  • 권장: Immutable 또는 TrafficSplitting
    • Immutable: 새 인스턴스 그룹을 먼저 띄우고 health check 통과 후에만 트래픽을 전환. warmup이 완료되지 않은 인스턴스에 트래픽이 가지 않음.
    • TrafficSplitting: 소량의 트래픽만 먼저 보내고 점진적으로 확대. canary 방식으로 warmup 시간 확보.
cupix-infrastructure/cupix-service/api-eb/main.tf:169hcl
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초)
cupix-infrastructure/cupix-service/api-eb/main.tf:171-172hcl
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.newhttp_open_timeout, http_read_timeout을 명시적으로 설정하여 외부 호출 지연이 전체 응답 시간에 미치는 영향을 제한.

Monitoring#

  • create_upload_credentials P95 latency 알림 (threshold: 500ms)
  • 배포 직후 리전별 latency spike 모니터링
text
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_* 설정 확인
  • 현재 설정: Rolling deployment, 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