A metric is a time series with identity
A CloudWatch metric belongs to a namespace and is identified by its metric name plus a set of dimensions. CPUUtilization for each InstanceId is a separate time series; changing dimensions creates a different metric.
flowchart LR SRC["EC2 hypervisor<br/>or CloudWatch Agent"] --> NS["Namespace<br/>AWS/EC2"] NS --> M["Metric<br/>CPUUtilization"] M --> D["Dimension<br/>InstanceId=i-0123"] D --> P["Datapoints<br/>timestamp + value"] P --> ST["Statistic over a period<br/>Average, p99"] ST --> DB["Dashboard<br/>and alarms"] %% step SRC: AWS services publish metrics automatically; the agent or your code adds custom ones. %% step NS: Namespaces group metrics: AWS/EC2, AWS/RDS, or your own like MyApp. %% step M: The metric name says what is measured. %% step D: Dimensions identify which resource; each combination is its own time series. %% step P: Each datapoint is a timestamp and a value. %% step ST: You read a statistic (Average, Sum, Maximum, a percentile) over a period such as 5 minutes. %% step DB: Dashboards graph them and alarms watch them.
Default and custom metrics
EC2 basic monitoring provides five-minute points; detailed monitoring provides one-minute points for an extra charge. RAM, filesystem usage, and process metrics are not default EC2 metrics — the hypervisor cannot see inside the guest — so use the CloudWatch Agent or custom metrics.
Custom metrics use 60-second standard resolution; high resolution uses one-second storage resolution and permits shorter alarm periods at higher cost. Publish with PutMetricData or, cheaper at volume, the Embedded Metric Format (EMF): JSON log lines that CloudWatch turns into metrics. Retry with backoff when APIs throttle.
Statistics and retention
| Statistic | Answers |
|---|---|
| Average | Typical load |
| Maximum / Minimum | Worst and best moments |
| Sum | Totals, e.g. requests or errors per period |
| SampleCount | How many datapoints |
| p90, p99 (percentiles) | Latency most users really feel |
CloudWatch keeps data for 15 months, with lower resolution as data ages: 1-minute points for 15 days, 5-minute for 63 days, 1-hour for 15 months. Metric math combines metrics, for example error rate = errors / requests × 100.
Dashboards
A dashboard can display metrics from multiple Regions and accounts when configured, plus text, alarms and Logs Insights results. Build one per service showing the four golden signals: latency, traffic, errors and saturation. A dashboard does not replace an alarm; a graph only visualizes data and nobody watches it at 3 a.m.
Other useful views: automatic dashboards per service, Container Insights for ECS/EKS, and CloudWatch Application Signals or Synthetics canaries that test endpoints from outside.
Cost awareness
Each custom metric (each unique name + dimension combination) costs money per month. Avoid high-cardinality dimensions such as user ID or request ID — they create thousands of metrics. Put those in logs instead.
| Command | Purpose |
|---|---|
aws cloudwatch list-metrics --namespace AWS/EC2 --dimensions Name=InstanceId,Value=i-0123456789abcdef0 |
Discover metrics |
aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization --dimensions Name=InstanceId,Value=i-0123456789abcdef0 --statistics Average --period 300 --start-time 2026-11-05T00:00:00Z --end-time 2026-11-05T06:00:00Z |
Read datapoints |
aws cloudwatch put-metric-data --namespace MyApp --metric-name QueueDepth --value 42 |
Publish a custom metric |
Traps: looking for memory in the default EC2 metrics; changing a dimension and wondering where the history went; using user IDs as dimensions.