Api::V1::CapturesController#create_voxels_upload_credentials (avg 1203ms, max 1203ms)
RCA: Api::V1::CapturesController#create_voxels_upload_credentials Latency (1203ms)
Overview#
What Happened#
2026-05-27 06:00:43 UTC에 us-west-2 리전의 cupixworks-api 서비스에서 POST /api/v1/captures/:id/voxels_upload_credentials 엔드포인트가 1203ms 응답 시간을 기록했다. 이는 APM latency threshold(500ms)를 초과한 것으로 감지되었으나, 에러 없이 HTTP 200으로 정상 응답했다.
Quick Facts#
| Field | Value |
|---|---|
| resource_name | Api::V1::CapturesController#create_voxels_upload_credentials |
| top_frame | app/services/cupix/storage_service.rb:138 |
| env | production, us-west-2 |
| avg_duration | 1203ms |
| HTTP status | 200 (정상 응답) |
Timeline#
- 2026-05-27T06:00:43.572Z — APM에서 1203ms latency span 감지
- 2026-05-27T15:41:56Z — RCA 분석 시작
Error Log#
{
"resource_name": "Api::V1::CapturesController#create_voxels_upload_credentials",
"service": "cupixworks-api",
"occurrences": 1,
"avg_ms": 1203,
"max_ms": 1203,
"sample_trace_id": "144056515843903871"
}
Impact#
- Service:
cupixworks-api - 발생 횟수: 1
- 최초 발생: 2026-05-27T06:00:43.572Z
- 최근 발생: 2026-05-27T06:00:43.572Z
이 엔드포인트는 voxel 업로드 전 클라이언트가 AWS 임시 자격 증명을 요청하는 용도로, 응답 지연은 업로드 시작 시점을 늦출 수 있으나 기능적 장애를 유발하지는 않는다.
Root Cause Summary#
이 latency는 Cupix::StorageService.get_credential_token 메서드 내에서 AWS STS get_federation_token API를 동기적으로 호출하기 때문에 발생한다. AWS STS API 호출은 네트워크 왕복 시간을 포함하여 통상 800~1200ms가 소요되며, 이는 이 엔드포인트의 구조적 특성이다. 생성된 자격 증명에 대한 캐싱 메커니즘이 없어 매 요청마다 STS API를 호출한다.
Technical Analysis#
Code Path#
- Entry point:
app/controllers/concerns/voxels_controller.rb:27 - Repository layer:
app/repositories/concerns/voxels_repository.rb:27 - Model layer:
app/models/concerns/voxel_module/s3.rb:28 - Failure point (latency source):
app/services/cupix/storage_service.rb:138
- Controller에서
repository_instance.create_voxels_upload_credentials호출:
def create_voxels_upload_credentials
credentials = repository_instance.create_voxels_upload_credentials
render_json 200, credentials
end
- Repository에서 권한 확인 후 모델 메서드 호출:
def create_voxels_upload_credentials(params = {})
raise Cupix::Errors::PermissionDenied.new(code: 'PERM10000', reason: 'Permission denied') unless @model.updatable_by?(self.current_user)
@model.voxels_upload_credentials
end
- Model에서 상태 전환(DB write) + STS 자격 증명 생성:
def voxels_upload_credentials
self.uploading_voxel_state
Cupix::StorageService.upload_credentials(
storage_option: storage_option,
id: id,
bucket_name: storage_option.s3_hosting_bucket_name,
key: voxels_basepath(voxels_upload_revision)
)
end
- 핵심 latency 원인 —
upload_credentials에서get_credential_token호출 후 AWS STS API를 동기적으로 실행:
def upload_credentials(storage_option: nil, **kwargs)
opts = parse_storage_option(storage_option).merge(kwargs)
check_required_params(opts, %i[id region bucket_name key])
expiration_in = opts[:expiration_in] || 4.hour
expires_at = expiration_in.from_now
token = get_credential_token(
storage_option: storage_option,
name: "#{Rails.env}-#{opts[:id]}-#{Time.now.to_i}",
policy: upload_credential_policy(opts[:bucket_name], opts[:key]),
duration_seconds: expiration_in.to_i
)
- AWS STS 동기 호출 (1000~1200ms 소요):
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
# NOTE: MinIO doesn't support get_federation_token
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) # <-- 주요 latency 원인
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
기대 동작: 클라이언트가 voxel 업로드를 위한 임시 자격 증명을 빠르게 받아야 함.
실제 동작: AWS STS get_federation_token 호출이 ~1000-1200ms 소요되어 전체 응답 시간이 1203ms로 측정됨. 이는 AWS STS API의 정상적인 응답 시간 범위이며, 코드 버그가 아닌 구조적 특성.
Log Evidence#
Datadog에서 동일 시간대 해당 엔드포인트 로그를 검색한 결과, 모든 요청이 HTTP 200으로 정상 응답했고 에러는 없었다.
service:cupixworks-api "create_voxels_upload_credentials"
Time range: 2026-05-27T05:00:00Z to 2026-05-27T07:00:00Z
대표 로그 항목:
[200] POST /api/v1/captures/41190/voxels_upload_credentials (Api::V1::CapturesController#create_voxels_upload_credentials)
[200] POST /api/v1/captures/41203/voxels_upload_credentials (Api::V1::CapturesController#create_voxels_upload_credentials)
[200] POST /api/v1/captures/73365/voxels_upload_credentials (Api::V1::CapturesController#create_voxels_upload_credentials)
에러 로그 검색:
service:cupixworks-api status:error "CapturesController"
Time range: 2026-05-27T05:00:00Z to 2026-05-27T07:00:00Z
Result: 0 logs (에러 없음)
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | AWS STS get_federation_token API 호출의 네트워크 latency가 주요 원인 |
코드 경로에서 유일한 외부 API 호출 (storage_service.rb:138). AWS STS는 통상 800-1200ms 소요. 1203ms는 이 범위 내. |
— | Confirmed |
| H2 | DB state transition (uploading_voxel_state)이 latency 유발 |
s3.rb:29에서 DB write 발생. |
DB write는 통상 5-20ms. 1203ms 중 극히 일부만 차지. 에러도 없음. | Rejected |
| H3 | STS client 초기화(Aws::STS::Client.new)에서 과도한 시간 소요 |
storage_service.rb:17에서 매 요청마다 새 client 생성 (pooling 없음). |
Client 초기화는 통상 10-30ms. 전체 latency의 주요 원인이 되기 어려움. | Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
- 없음 — 1203ms latency는 AWS STS API의 정상 응답 시간 범위이며, 에러 없이 정상 동작 중. occurrence_count가 1건이므로 즉시 조치는 불필요.
단기 개선 (1주 이내)#
- APM latency threshold 조정 고려: 이 엔드포인트는 AWS STS 호출이 필수적이므로 500ms threshold가 적절하지 않음. resource-specific threshold를 1500ms 이상으로 올리거나, 이 endpoint를 latency 모니터링 예외 목록에 추가하는 방안 검토.
- STS Client 재사용:
storage_service.rb:14-18에서 매 요청마다Aws::STS::Client.new를 호출하고 있음. Thread-safe한 client pool을 적용하면 10-30ms 절약 가능.
장기 개선 (재발 방지)#
- 임시 자격 증명 캐싱: 동일 capture에 대한 반복 요청 시, TTL 내 기존 자격 증명을 재사용하는 캐싱 레이어 도입 (Redis/in-memory).
duration_seconds: 4.hours이므로 캐시 TTL을 3.5시간으로 설정하면 안전하게 재사용 가능. - Pre-signed URL 방식 전환: STS federation token 대신 S3 pre-signed URL을 사용하면 서버 측 서명만으로 완료되어 외부 API 호출 없이 ~10ms 이내 응답 가능. 단, 업로드 구조 변경이 필요.
Monitoring#
- APM에서 이 resource의 p95/p99 latency 추이를 추적하여, STS latency가 지속적으로 증가하는지 확인:
avg:trace.rack.request.duration{service:cupixworks-api,resource_name:api_v1_captures_create_voxels_upload_credentials} by {availability-zone}
- STS 호출 실패율 모니터:
service:cupixworks-api "SYS20000" "Can't create temporary token"
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial — 이는 코드 버그가 아닌 AWS STS API의 정상적인 latency 특성. 발생 건수가 1건이며 기능적 영향 없음. Latency threshold 조정이나 false-positive 필터링으로 해결 가능.