Skip to content

CloudWatch

Amazon CloudWatch is the AWS metric store, alarm engine and dashboard service. Most AWS services publish metrics to it without any configuration; the more managed the service, the more it publishes.

There are three things to keep separate:

  • Service metrics — published by AWS on your behalf from outside the instance or resource. Free, and available as soon as the resource exists.
  • Agent metrics — collected from inside an EC2 instance or on-premises server by the CloudWatch agent. The hypervisor cannot see memory pressure or filesystem usage, so anything from inside the guest requires the agent. These are published as custom metrics and are charged.
  • Alarms — a rule watching one metric (or a metric-math expression) over a period, moving between OK, ALARM and INSUFFICIENT_DATA, and firing an action such as an SNS notification or an Auto Scaling policy.

The most commonly needed agent metrics are memory utilisation and disk space used, on EC2. Neither is available without the agent.

For EC2, basic monitoring publishes a data point every 5 minutes and is free; detailed monitoring publishes every minute and is charged. Set an alarm period of at least 300 seconds against a basic-monitoring metric and at least 60 seconds against a detailed-monitoring one — an alarm evaluated more often than the metric arrives will sit in INSUFFICIENT_DATA.

Status check metrics are the exception: they are published at 1-minute resolution at no charge by default.

Custom metrics you publish yourself are standard resolution (1 minute) unless you declare them high resolution, in which case CloudWatch stores them at 1-second granularity. High-resolution metrics and the 10- or 30-second alarms that go with them cost more.

  • CPUUtilization — percentage of physical CPU time used by the instance.
  • NetworkIn / NetworkOut, and NetworkPacketsIn / NetworkPacketsOut — the packet counts are published for basic monitoring only, at 5-minute periods, so they do not get finer when you turn detailed monitoring on.
  • StatusCheckFailed, and its _Instance, _System and _AttachedEBS variants.
  • DiskReadOps, DiskWriteOps, DiskReadBytes, DiskWriteBytesthese cover instance store volumes only. If the instance has no instance store volumes the value is zero or the metric is not reported at all. This trips people up constantly, because the great majority of instances boot from EBS and so report nothing here.
  • EBSReadOps, EBSWriteOps, EBSReadBytes, EBSWriteBytes, EBSIOBalance%, EBSByteBalance% — EBS activity aggregated across the volumes attached to the instance. Published in AWS/EC2 for volumes attached to Nitro-based instances that are not bare metal.
  • InstanceEBSIOPSExceededCheck and InstanceEBSThroughputExceededCheck — whether the instance tried to exceed its own EBS IOPS or throughput limits, which is a different constraint from the volume’s limits.

Per-volume metrics live in their own namespace: volume read and write operations and bytes, VolumeQueueLength, and VolumeStalledIOCheck on Nitro instances. Use these when you need to know which volume is the bottleneck; use the EBS* metrics in AWS/EC2 when you need the instance-level total.

CPU utilisation, freeable memory, database connections, and free storage space. Between them these catch the four ways an instance typically runs out of headroom.

Request count, healthy and unhealthy host counts, and HTTP response code counts split by class — the 4XX and 5XX series, and separately the codes generated by the load balancer itself versus by the target.

Invocations, errors, duration, throttles, and concurrent executions. Errors and throttles are the two that belong on an alarm from day one.

  • Metric math builds derived series — an error rate from an error count and a request count, for example — and you can alarm on the result.
  • Anomaly detection models a metric’s normal band from its history and alarms on departures from it, rather than on a fixed threshold. This is the right tool for metrics with a daily or weekly shape.
  • OpenTelemetry metrics are ingested natively, at the resolution they are sent, and can be alarmed on with PromQL queries.
  • Cross-account observability links source accounts to a monitoring account so one CloudWatch console can graph and query across an estate.