Zettelkasten

enhanced Container Insights는 TaskId로 series를 폭증시키지만 CloudWatch proration이 비용을 수렴시킨다

·수정 2026.06.11·수정 1

요약

  • ECS Container Insights의 enhanced 모드는 컨테이너/태스크 단위 메트릭을 발행하는데, dimension에 ephemeral한 TaskId가 들어간다.
  • task가 배포·재시작될 때마다 새 TaskId가 발급되고, CloudWatch는 (TaskId × ContainerName × MetricName) 조합 하나하나를 별도 커스텀 메트릭으로 카운트한다.
  • 하지만 custom metric은 시간 단위로 prorate되므로 series 개수가 폭증해도 청구는 활성 시간 합으로 수렴한다. 비용 동인은 회전율이 아니라 동시 task-hours × per-task/container 메트릭 수이며, 회전율은 시간 반올림 프리미엄만 더한다. (아래 "정정" 참조 — 이 노트의 원래 제목 가설은 청구서 실측으로 뒤집혔다)

본문

관찰된 현상

한 prod 서비스 클러스터에서 동시 실행 task는 19개뿐인데, 단일 메트릭 ContainerCpuUtilization 하나가 3,352개의 시계열(series) 을 가지고 있었다. list-metrics로 dimension을 까보면:

dimension 조합별 series 수:
  1,668  ClusterName + ContainerName + TaskDefinitionFamily + TaskId
  1,667  ClusterName + ContainerName + ServiceName          + TaskId
      8  ClusterName + ContainerName + ServiceName            (집계용)
      8  ClusterName + ContainerName + TaskDefinitionFamily   (집계용)
      1  ClusterName                                          (집계용)
─────────────────────────────────────────────────────────
  3,352

각 dimension의 고유값:
  TaskId               : 1,657 개   ← 폭증의 원인
  ContainerName        :     6 개
  ServiceName          :     7 개
  TaskDefinitionFamily :     7 개
  ClusterName          :     1 개

왜 series가 수천 개로 불어나는가

  1. TaskId는 task 생애마다 새로 발급되는 ephemeral 식별자다. list-metrics는 최근 약 14일간 활동한 메트릭만 반환하는데, 그 안에 고유 TaskId가 1,657개 등장했다. 동시 19개 task로 14일에 1,657개 → 하루 100개 이상의 task가 떴다 사라진 것. 롤링 배포(배포 1회 = 전체 task 교체), 오토스케일링, health check 실패 재시작이 원인. task 하나가 죽고 새로 뜰 때마다 완전히 새로운 메트릭 series 묶음이 생성된다.

  2. enhanced 모드는 같은 메트릭을 두 벌로 발행한다. ServiceName 기준과 TaskDefinitionFamily 기준으로 중복 발행되어 series가 ×2 된다 (1,668 + 1,667).

  3. 컨테이너 단위 메트릭이 20종 이상이다. ContainerCpuUtilization 하나가 3,352개인데, ContainerMemoryUtilized, ContainerNetworkRxBytes 등 동일 구조의 컨테이너 단위 메트릭이 20종 넘게 같이 발행된다.

비용 메커니즘

CloudWatch 커스텀 메트릭(CW:MetricsUsage)은 (이름 + namespace + dimension) 조합마다 별도 메트릭으로 과금된다. 고cardinality dimension인 TaskId가 조합 수(series)를 폭증시킨다.

정정 — proration으로 비용은 수렴한다 (청구서 실측)

작성 당시엔 series 개수(3,352)에 비례해 비용이 무한 누적된다고 봤지만, 청구서를 까보니 그렇지 않다.

  • custom metric은 시간 단위로 prorate된다. 메트릭은 데이터를 받은 시간만큼만 과금되고, 짧게 살다 죽은 ephemeral series는 그만큼만 청구된다. 1,657개 TaskId가 만든 수천 series가 각각 풀월로 과금되는 게 아니라 활성 시간 합으로 수렴한다.
  • 실측: enhanced CI 메트릭은 CW:MetricsUsage에서 **0.07/metric(enhanced전용할인율,0.07/metric**(enhanced 전용 할인율, 0.30 아님)로 과금됐고, 실제 청구된 메트릭은 약 3,621개 ≈ $253/월. 3,352 series × 풀월이 아니다.
  • 정확한 비용 동인 ≈ 동시 task-hours × per-task/container 메트릭 수. 동시 task 수 × 가동 시간이 지배적이고, 회전율은 "1시간 미만 task도 최소 1시간 과금"되는 시간 반올림 프리미엄만 더한다.
  • 즉 이 노트의 원래 가설("동시 task 수와 무관, 회전율에 비례")은 과장이다. cardinality가 series를 부풀리는 건 맞지만, 비용은 proration이 잡아준다.

실제 1순위 비용은 CI 메트릭이 아니었다

같은 계정 CloudWatch 월 청구를 분해하니 1위는 관측 SaaS로 보내는 CloudWatch Metric Stream(CW:MetricStreamUsage, 전체의 ~54%) 이었고, 그 82.5%가 ALB 메트릭이었다. enhanced CI custom metric은 2위. "TaskId/CI가 비용 주범"이라는 프레임은 부분적으로만 맞았다 — 고cardinality 메트릭을 metric stream으로 외부에 분당 푸시하면 stream update 과금이 custom metric보다 더 크게 터질 수 있다. 비용 분석은 series 수 추정이 아니라 usage type별 청구서(Cost Explorer) 로 시작해야 한다.

대응

  • enhancedstandard(enabled) 다운그레이드: 컨테이너/TaskId 단위 메트릭이 사라지고 Service·Cluster 집계 위주로 바뀌어 series 수가 수천 → 수십 규모로 급감한다. dev/qa부터 적용하면 즉효. AWS 공식 메트릭 표 기준 standard 네임스페이스엔 TaskId·ContainerName dimension이 아예 없다(=enhanced가 추가한 축). 단 per-task/container 드릴다운 가시성은 잃으므로, 그게 APM 등으로 대체되는지 먼저 확인.
  • 기본 AWS/ECS 네임스페이스 메트릭(CPUUtilization, MemoryUtilization)은 서비스/클러스터 단위 집계라 무료이고 task 수에 비례하지 않는다. 세부 컨테이너 메트릭이 꼭 필요한 게 아니면 enhanced의 ROI가 낮다.
  • 일반 원칙: 모니터링 dimension에 ephemeral 식별자(TaskId, PodName, RequestId 등)를 넣으면 cardinality가 무한 증식한다. 비용/성능 모두를 위해 dimension은 stable한 축(Service, Cluster)으로 제한한다.

관련 노트

참고