Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive · AWS

CloudWatch Container Insights for ECS

Turn on Container Insights for ECS clusters on Fargate or EC2, understand the metrics and performance logs, build alarms and dashboards, and control the cost.

3 min read

  • Amazon ECS
  • CloudWatch Container Insights
  • AWS Fargate
  • CloudWatch Logs Insights

Running containers on ECS without per-service CPU, memory and network metrics means guessing during incidents. CloudWatch Container Insights collects those metrics for clusters, services and tasks and stores detailed performance records as logs you can query. For Fargate it needs no agent; for EC2-backed clusters it uses a small daemon container.

State of AWS on this date. Container Insights for ECS supports Fargate (platform version 1.4.0 and later) and EC2 launch types. It is billed as custom metrics plus the ingestion and storage of the performance log events, so it adds to the bill; the sections below show how to keep that small.

What gets collected

flowchart TB
  subgraph CL[ECS cluster]
    T1[Task A<br/>Fargate] --> AGT
    T2[Task B<br/>Fargate] --> AGT
    EC[EC2 container instance<br/>CloudWatch agent daemon] --> AGT
  end
  AGT[Task and instance telemetry] --> PL[Log group /aws/ecs/containerinsights/cluster/performance]
  PL --> MET[Metrics in namespace ECS/ContainerInsights<br/>extracted automatically]
  MET --> DB[Automatic dashboards in CloudWatch]
  MET --> AL[Alarms on CPU memory restarts]
  PL --> LI[Logs Insights queries<br/>per task detail]
  APP[Application stdout] -->|awslogs driver| AL2[Application log group]

Container Insights and your application logs are separate: the first is infrastructure telemetry, the second is what your code prints. Keep both.

Enable it

For a new cluster:

aws ecs create-cluster --cluster-name prod --settings name=containerInsights,value=enabled

For an existing cluster:

aws ecs update-cluster-settings --cluster prod --settings name=containerInsights,value=enabled
aws ecs describe-clusters --clusters prod --include SETTINGS --query 'clusters[0].settings'

Or make it the default for every new cluster in the region:

aws ecs put-account-setting-default --name containerInsights --value enabled

On EC2 capacity, also run the CloudWatch agent as a daemon service on each container instance (AWS provides a ready-made task definition and quick-start CloudFormation template). Fargate tasks emit the data natively.

Metrics you get

Metric (namespace ECS/ContainerInsights) Dimension level Use
CpuUtilized, CpuReserved cluster, service, task Compare used with reserved to right-size
MemoryUtilized, MemoryReserved cluster, service, task Memory leaks, out-of-memory risk
NetworkRxBytes, NetworkTxBytes service, task Traffic and spikes
StorageReadBytes, StorageWriteBytes service, task Disk usage patterns
RunningTaskCount, DesiredTaskCount, PendingTaskCount cluster, service Health of deployments
ServiceCount, ContainerInstanceCount, TaskCount cluster Capacity

Calculate percentages with metric math: MemoryUtilized / MemoryReserved * 100. Fargate tasks have fixed CPU and memory sizes (for example 0.25 vCPU / 512 MB), so utilisation above 80% of reserved is a signal to move up a size or add tasks.

Alarms that matter

aws cloudwatch put-metric-alarm --alarm-name prod-api-running-low \
  --namespace ECS/ContainerInsights --metric-name RunningTaskCount \
  --dimensions Name=ClusterName,Value=prod Name=ServiceName,Value=api \
  --statistic Minimum --period 60 --evaluation-periods 3 --threshold 2 \
  --comparison-operator LessThanThreshold --treat-missing-data breaching \
  --alarm-actions arn:aws:sns:ap-south-1:111111111111:ops-alerts

Also alarm on: memory above 85% of reserved for 10 minutes, DesiredTaskCount greater than RunningTaskCount for 5 minutes (a stuck deployment), and load balancer 5xx or unhealthy hosts (from the ALB metrics, not Container Insights).

Query the performance logs

In CloudWatch Logs Insights, pick /aws/ecs/containerinsights/prod/performance:

fields @timestamp, ServiceName, TaskId, CpuUtilized, MemoryUtilized
| filter Type = "Task" and ServiceName = "api"
| sort MemoryUtilized desc
| limit 20
stats avg(CpuUtilized) as cpu, max(MemoryUtilized) as mem by bin(5m), ServiceName
| filter Type = "Task"

This finds the heaviest task, restart patterns and growth over time, with per-task detail the aggregate metrics hide.

Cost controls

  • Enable on production clusters; for dev, enable only while testing.
  • Set retention on the performance log group (for example 14 days): aws logs put-retention-policy --log-group-name /aws/ecs/containerinsights/prod/performance --retention-in-days 14.
  • Prefer few clusters with several services over many tiny clusters; metrics are per cluster, service and task.
  • Review the CloudWatch line of the bill in Cost Explorer after the first week.

Troubleshooting

  • No data: the setting is enabled but tasks started before enabling need restarting; Fargate platform must be 1.4.0 or later.
  • Metrics for stopped tasks disappear: short-lived tasks are visible only in the performance logs.
  • Dashboards empty: wrong region, or the cluster name does not match the ClusterName dimension.
  • Application logs missing: check the task definition’s logConfiguration (awslogs driver) and the task execution role permissions, which are independent of Container Insights.