ES /docs

Api::V1::MeasurementsController#index (avg 1028ms, max 1028ms)

RCA: Api::V1::MeasurementsController#index Latency (1028ms)

Overview#

What Happened#

2026-05-27 03:32 UTC에 ap-southeast-2 리전의 cupixworks-api 서비스에서 MeasurementsController#index 엔드포인트가 1028ms의 응답 시간을 기록했다. 결과는 0건(빈 응답)이었음에도 불구하고 높은 지연이 발생했으며, DB 시간은 62ms에 불과해 약 964ms가 인증/미들웨어 계층에서 소비된 것으로 분석된다.

Quick Facts#

Field Value
resource_name Api::V1::MeasurementsController#index
duration 1028ms (DB: 62ms, View: 0.09ms, Serialization: 0ms)
top_frame app/controllers/api/v1/measurements_controller.rb:14
runtime Ruby on Rails (Cognito auth)
deploy production-ap-southeast-2-20260526t0527z0-dd7bd097-cupixworks
env production, ap-southeast-2

Timeline#

  1. 2026-05-27T03:30:12Z — 동일 호스트(ip-10-1-145-251)에서 다른 엔드포인트(ReviewsController) 624ms 지연 발생
  2. 2026-05-27T03:32:10Z — MeasurementsController#index 요청 1028ms 기록 (review_key: qqgtdc, user: built.com.au)
  3. 2026-05-27T03:35:24Z — 동일 엔드포인트 다른 호스트에서 848ms 지연 (user: downer.co.nz)
  4. 2026-05-27T04:21:40Z — ap-southeast-2에서 다수의 Operation timed out after 10002 milliseconds 에러 발생

Error Log#

Datadog Logs

json
{
  "resource_name": "Api::V1::MeasurementsController#index",
  "service": "cupixworks-api",
  "occurrences": 1,
  "avg_ms": 1028,
  "max_ms": 1028,
  "sample_trace_id": "2094942667927055673"
}

Impact#

  • Service: cupixworks-api
  • 발생 횟수: 1
  • 최초 발생: 2026-05-27T03:32:08.760Z
  • 최근 발생: 2026-05-27T03:32:08.760Z

Root Cause Summary#

ap-southeast-2 리전의 특정 호스트(ip-10-1-145-251)에서 인프라 수준의 일시적 성능 저하가 발생했다. 요청이 0건의 결과를 반환했음에도 1028ms가 소요된 이유는, DB 처리(62ms)와 직렬화(0ms)를 제외한 약 964ms가 Cognito 인증 검증(Cupix::Auth::Verification#verify_authenticated_request!) 및 before_action 필터 체인(set_review → ReviewRepository#show)에서 소비되었기 때문이다. 동일 호스트가 같은 시간대에 다른 컨트롤러에서도 지연을 보였고, 약 50분 후 리전 전체에서 타임아웃 에러가 발생한 점으로 볼 때, 이는 호스트 또는 리전 네트워크의 일시적 불안정에 의한 것이다.

Technical Analysis#

Code Path#

  • Entry point: app/controllers/api/v1/measurements_controller.rb:14
  • Authentication: app/controllers/concerns/verification_controller.rb:15-35
  • Before action: app/controllers/concerns/parameter_required.rb:27-29 (set_review)
  • Search: app/repositories/measurement_repository.rb:265-325
  • Permission joins: app/repositories/base_repository.rb:70-98

요청 처리 흐름:

  1. Cognito 인증 검증 — 외부 서비스 호출 포함
app/controllers/concerns/verification_controller.rb:15-35ruby
def authenticate!
  if @cupix_auth_method == 'COGNITO'
    begin
      verification = Cupix::Auth::Verification.new(request: request)
      response = verification.verify_authenticated_request!
    rescue Cupix::Errors::Unauthorized => e
      if %w[AUTH20000].include?(e.code) && authenticate_public_accessible_review_access == true
        return
      else
        raise e
      end
    end

    @current_user = response.user
    @current_team = response.team
    @session = response.session
    Current.access_token = verification.access_token
  else
    legacy_authenticate!
  end
end

이 단계에서 Cognito 토큰 검증을 위한 외부 네트워크 호출이 발생한다. 네트워크 지연이 있을 경우 수백 ms가 소비될 수 있다.

  1. set_review before_action — ReviewRepository 조회
app/controllers/concerns/parameter_required.rb:27-29ruby
def set_review
  @review = ReviewRepository.new(current_user: current_user).show(params[:review_key])
end

review_key qqgtdc로 ReviewRepository#show를 호출하며, 내부적으로 permission_joins가 적용된다.

  1. MeasurementsController#index 실행 — Elasticsearch 검색 + SQL permission joins
app/controllers/api/v1/measurements_controller.rb:14-23ruby
def index
  measurement_query_option = Cupix::QueryOption::Measurement.new(get_query_option, params)
  measurements = repository_instance.search(measurement_query_option)

  render_api Renderable.new({
    search_result: measurements,
    is_collection: true,
    serializer_option: @serializer_option
  })
end
  1. _search 내부에서 ReviewRepository 재조회
app/repositories/measurement_repository.rb:280-283ruby
review = ReviewRepository.new(current_user: self.current_user).show(self.query_option.review_key)
raise Cupix::Errors::NotFound.new(code: 'ARG10000', reason: 'review not found') if review.blank?

facility = review.facility

set_review before_action과 _search 메서드 양쪽에서 ReviewRepository#show가 중복 호출된다. 각 호출은 permission_joins (11개 LEFT JOIN)를 포함한 복잡한 쿼리를 실행한다.

기대 동작: 빈 결과셋에 대해 100ms 이내 응답 실제 동작: 1028ms 소요, DB 62ms + 인증/미들웨어 964ms

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-api resource_name:"Api::V1::MeasurementsController#index" @duration:>500ms env:production

핵심 로그 (일치하는 요청):

json
{
  "timestamp": "2026-05-27T03:32:10.939Z",
  "resource_name": "Api::V1::MeasurementsController#index",
  "duration_ms": 1026.71,
  "db_ms": 62.17,
  "view_ms": 0.09,
  "serialization_ms": 0,
  "per_page": 100,
  "page": 1,
  "total_entries": 0,
  "total_pages": 1,
  "review_key": "qqgtdc",
  "host": "ip-10-1-145-251.ap-southeast-2.compute.internal",
  "user": "Ermias Wedajo (built.com.au)",
  "team_id": 16,
  "auth_method": "COGNITO"
}

동일 호스트의 다른 지연 요청:

text
2026-05-27T03:30:12.891Z - 624.97ms - review_key:vxoj2g (Cupix Support, team: mtpo-vida)
2026-05-27T03:32:10.939Z - 1026.71ms - review_key:qqgtdc (Ermias Wedajo, team: built)

약 50분 후 리전 타임아웃 에러:

text
2026-05-27T04:21:40Z - "Operation timed out after 10002 milliseconds with 0 bytes received"
  - PanoRepository, Admin::EditingRepository, ElementTraceRepository

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 호스트/리전 인프라 일시적 성능 저하 (Cognito 인증 네트워크 지연) 동일 호스트에서 다수 컨트롤러 지연 발생, DB 62ms vs 총 1028ms (964ms gap), 50분 후 리전 전체 타임아웃 에러 단일 발생이라 패턴 확증 어려움 Confirmed
H2 N+1 쿼리 또는 DB 성능 이슈 코드에 permission_joins 11개 LEFT JOIN 존재 DB 시간이 62ms로 전체의 6%에 불과, 결과 0건이므로 serialization 병목 없음 Rejected
H3 ReviewRepository 중복 호출로 인한 지연 set_review + _search에서 ReviewRepository#show 2회 호출 확인 (코드 확인) DB 시간 62ms에 두 쿼리 모두 포함됨, 주요 병목은 DB 외부 Contributing factor
H4 Ruby GC pause 또는 프로세스 경합 동일 호스트 다른 요청도 느림, 빈 결과에도 높은 지연 GC pause는 보통 수십 ms 수준이며 964ms는 과도함 Inconclusive

Fix Recommendation#

즉시 조치 (Critical)#

  • 현재 단일 발생(occurrence: 1)이며 인프라 일시적 이슈로 판단되어, 즉시 코드 수정은 불필요하다.
  • 모니터링을 추가하여 패턴 반복 여부를 확인한다.

단기 개선 (1주 이내)#

  • app/repositories/measurement_repository.rb:280_search 내 ReviewRepository#show 중복 호출 제거. set_review before_action에서 이미 조회한 @review를 재활용하도록 변경.
  • app/controllers/concerns/verification_controller.rb:18-19 — Cognito 인증 결과 캐싱 (동일 요청 내). 현재도 단일 요청이지만 미들웨어 간 중복 검증 방지.

장기 개선 (재발 방지)#

  • Cognito 토큰 검증에 대한 로컬 캐싱 레이어 도입 (JWT 서명 검증은 로컬에서 수행 가능, JWKS 키를 주기적으로 갱신).
  • ap-southeast-2 리전 호스트 상태 모니터링 강화 (특정 호스트에서 반복적 지연 발생 시 자동 드레인).
  • ReviewRepository 중복 호출 패턴은 다른 컨트롤러에서도 공통적으로 존재할 수 있으므로 전체 리팩토링 검토.

Monitoring#

  • MeasurementsController#index P95/P99 지연 시간 알림 (임계값: 500ms)
  • 호스트별 평균 응답 시간 이상 탐지
text
service:cupixworks-api resource_name:"Api::V1::MeasurementsController#index" @duration:>500ms env:production

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial
  • 단일 발생이며 인프라 일시적 이슈로 확인됨. 코드 레벨 최적화(ReviewRepository 중복 호출 제거)는 선택적 개선 사항.