How to Monitor EC2 with CloudWatch
Published on · Updated on
Corrected EC2 metric intervals and permissions, and added current agent, alarm, and status-check guidance.
Amazon EC2 sends built-in instance metrics to Amazon CloudWatch, including CPU, network traffic, and status checks. Basic monitoring is on by default: most EC2 metrics arrive every five minutes, while status-check metrics arrive every minute. Enable detailed monitoring when you need one-minute data for supported EC2 metrics.
EC2 does not report the guest operating system's memory use or filesystem space by default. Install the CloudWatch agent for those signals. Then match alarm periods to each metric's publishing interval, and use the correct response for the kind of failure an alarm detects.
Understand the EC2 metrics CloudWatch receives
EC2 publishes its built-in metrics in the AWS/EC2 namespace. For an individual instance, select the InstanceId dimension. A metric's name alone is not enough: namespace, metric name, dimensions, statistic, period, account, and Region all affect what CloudWatch displays or evaluates.
Built-in EC2 metrics are not operating-system measurements. For example, CPUUtilization is the percentage of physical CPU time EC2 uses for the instance, including guest and EC2 code; it can differ from a value shown by an operating-system tool. The EC2 metric reference documents each metric's meaning, unit, dimensions, and availability: CloudWatch metrics available for EC2 instances.
Enable detailed monitoring when one-minute EC2 data matters
Basic monitoring is the EC2 default. Most supported instance metrics use five-minute periods; detailed monitoring changes supported metrics to one-minute periods and is charged per metric EC2 sends. The setting does not change EBS volume monitoring or collect guest memory and filesystem metrics.
| Metric or source | What to expect |
|---|---|
Most supported AWS/EC2 instance metrics | Five minutes with basic monitoring; one minute for supported metrics with detailed monitoring. |
| EC2 status checks | One minute by default, at no charge; detailed monitoring is not needed. |
| CPU credit metrics | Five minutes only, including when detailed monitoring is enabled. |
| Network packet metrics | Available for basic monitoring at five-minute periods; they do not provide one-minute datapoints with detailed monitoring. |
| EBS volume metrics | Published per volume in AWS/EBS; EC2 detailed monitoring does not change their schedule. |
Enable detailed monitoring from the EC2 console by selecting an instance and choosing Actions > Monitor and troubleshoot > Manage detailed monitoring. You can also enable it for an existing instance with the AWS CLI:
aws ec2 monitor-instances --instance-ids i-0123456789abcdef0 --region us-east-1
Replace the example instance ID and Region with your own. The identity running the command needs the EC2 MonitorInstances permission. Use UnmonitorInstances to turn detailed monitoring off. If a one-minute CPU or network signal matters for an alarm or scaling decision, this setting can shorten the wait for an EC2 datapoint; it does not guarantee an end-to-end response within one minute. AWS lists the intervals, exceptions, permissions, and current pricing link in its detailed monitoring guide. For a closer comparison, see our EC2 basic and detailed monitoring guide.
Give the CloudWatch agent an EC2 role
For guest operating-system metrics, attach an instance role trusted by the EC2 service through an instance profile. AWS's CloudWatchAgentServerPolicy is its documented starting policy for sending agent metrics and, when configured, logs. Review its current permissions against the telemetry you enable, and avoid putting long-lived access keys on the server.
Managing the agent through Systems Manager is a separate choice. The instance must also have the permissions and connectivity required for Systems Manager; these are not substitutes for the agent's publishing permissions. Likewise, the user or automation that enables detailed EC2 monitoring needs ec2:MonitorInstances, not an agent policy. See AWS's CloudWatch agent IAM and network prerequisites and CloudWatchAgentServerPolicy reference.
Install the CloudWatch agent for memory and filesystem metrics
The following example targets a Linux EC2 instance running Amazon Linux 2023. Install the agent package with DNF:
sudo dnf install amazon-cloudwatch-agent
The package is available for Amazon Linux 2023 in AWS's CloudWatch agent download guide; Amazon Linux 2023 uses DNF as its package manager.
Save this configuration as /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json. It collects memory usage and the used-space percentage for the root filesystem once a minute:
{
"agent": {
"metrics_collection_interval": 60
},
"metrics": {
"namespace": "CWAgent",
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"mem": {
"measurement": ["used_percent"]
},
"disk": {
"resources": ["/"],
"measurement": ["used_percent"]
}
}
}
}
Start the agent with the saved file, then check that it is running:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
The agent publishes these metrics in CWAgent by default, separate from EC2's AWS/EC2 namespace. In the example, the measurements appear as mem_used_percent and disk_used_percent. In CloudWatch, check for the expected metric names, instance ID, and filesystem path. Disk metrics describe the selected operating-system mount point; add other paths only when you need them. The agent's filesystem dimensions can distinguish paths and filesystems, so select the exact dimensions shown in CloudWatch when creating an alarm. This is not the same as per-volume EBS performance monitoring. For application-specific signals beyond EC2 and operating-system metrics, see our CloudWatch custom metrics guide.
An EC2 instance also needs network access to the CloudWatch endpoint in its Region. For private subnets, provide the required VPC endpoints or another supported network route. AWS documents supported installation methods, agent configuration, and metric names in the CloudWatch agent installation guide, configuration examples, and collected metrics reference.
Create alarms for conditions that need a response
Choose a metric that signals a customer impact, a capacity limit, or a failure mode. Set the threshold from a service objective, tested limit, or operational requirement; there is no universal safe CPU, memory, or disk percentage for every workload.
Choose the metric and its meaning
CPU (
AWS/EC2/CPUUtilization). Percent of physical CPU used by the instance. UseAverageto see sustained load orMaximumto react to high datapoints; choose based on the workload and response.Memory (
CWAgent/mem_used_percent). Guest operating-system memory usage. Check the agent'sInstanceIddimension and consider available memory and workload behavior when setting a threshold.Filesystem space (
CWAgent/disk_used_percent). Used space for an operating-system filesystem, separated by the configured path and other filesystem dimensions. This is capacity, not disk throughput.Network bytes (
AWS/EC2/NetworkIn,NetworkOut). Bytes received or sent across all instance network interfaces during the period.Sumgives bytes in that interval; divide by period seconds for average bytes per second. Packet metrics count packets and are available at five-minute periods under basic monitoring.Disk I/O (
AWS/EC2/DiskReadBytes,DiskWriteBytes,DiskReadOps,DiskWriteOps). These instance-store metrics report bytes or operation counts during the period; divide theirSumby period seconds for average throughput or IOPS. They do not report filesystem free space or attached EBS activity. EBS has per-volume metrics inAWS/EBS; supported Nitro instances also provide EC2-level EBS aggregates.
For every alarm, confirm the namespace, metric name, full dimension set, statistic, and unit in the CloudWatch metric selector. For example, NetworkIn and NetworkOut use Bytes, while CPUUtilization is a Percent. Treating a per-period total as a rate, or choosing an alarm dimension that does not match the published series, can produce misleading graphs or no data.
Use the right status-check response
EC2 status checks run automatically and publish binary Count metrics in AWS/EC2: 0 means passed and 1 means failed. Supported status-check metrics are available every minute at no charge. The attached-EBS check is limited to Nitro instances. The failure type matters:
StatusCheckFailed_System: Underlying host or AWS infrastructure issue. Review AWS Health and the instance status. A CloudWatch recover action may be suitable for an eligible instance.StatusCheckFailed_Instance: Guest operating system, startup, or networking issue. A system failure can also cause an instance check to fail. Inspect system logs and guest configuration; reboot or replace only when appropriate. A recover action is not supported for this metric.StatusCheckFailed_AttachedEBS: An attached EBS volume cannot be reached or complete I/O. This check is available only on Nitro instances. Check the affected EBS volume and workload. Depending on the impact, wait for AWS. If the workload is not driving I/O to attached EBS volumes, a stop/start may move the instance to another host. If recovery requires replacing a volume or instance, use a tested restore or failover procedure and recover data from a known-good snapshot, backup, or replica.
Do not attach automatic recovery to a generic CPU, memory, or instance-status alarm. EC2's recovery action applies to StatusCheckFailed_System for supported instances; it does not repair an operating-system or application fault. AWS recommends treating missing data as missing for alarms with EC2 stop, reboot, terminate, or recover actions, because a telemetry gap must not trigger an unsafe response. See the AWS status-check guide and EC2 alarm-action guidance. For recovery eligibility and a complete alarm example, see our EC2 recovery alarm guide.
Match alarm periods and missing-data behavior to the metric
Period is the duration represented by each alarm datapoint. On basic monitoring, use a period of at least 300 seconds for most EC2 instance metrics; supported detailed metrics can use 60 seconds. Status-check metrics support 60-second periods with basic monitoring, and CPU credit metrics remain at 300 seconds. A shorter alarm period cannot create data that EC2 or the agent has not published.
EvaluationPeriods is the number of recent datapoints CloudWatch considers (N); DatapointsToAlarm is how many must breach (M). For example, 2 of 3 datapoints at a 300-second period means two breaching datapoints among the last three five-minute periods. They need not be consecutive, and the full evaluation window is 15 minutes. Choose M and N to balance detection time against normal variation; do not describe a five-minute period as an exact five-minute response guarantee.
Missing data can mean a quiet event metric, an agent that stopped, an instance that is initializing, or a CloudWatch reporting gap. CloudWatch's default treatment is missing; decide whether each signal should enter INSUFFICIENT_DATA, retain its current state, or treat silence as healthy or breaching. For status-check alarms with stop, reboot, terminate, or recover actions, use AWS's missing-data recommendation so a reporting gap does not count as a failed check. CloudWatch can also evaluate available real datapoints without applying the configured missing-data treatment when enough data exists. See AWS's alarm evaluation guide and missing-data behavior, and our guide to CloudWatch alarm thresholds and conditions.
Route alarm notifications to an owner
When creating an alarm in the CloudWatch console, choose an SNS topic for the alarm state that needs attention. Create the topic first, add the intended subscribers, and confirm email subscriptions before relying on delivery. Give every alert an owner and a response; use automatic EC2 actions only for failure modes the action can safely address.
Build a dashboard around useful signals
A CloudWatch dashboard can show metrics from the same account or other configured accounts and Regions. Start with signals that support an operational decision, such as instance CPU alongside application errors, request rate, and saturation. Keep the scope visible: a widget with one InstanceId answers a different question from a fleet aggregate.
Create a basic metric widget
You can create a dashboard in the CloudWatch console or with the AWS CLI. This example shows CPU for one instance using a 300-second period, suitable for basic monitoring:
{
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"region": "us-east-1",
"period": 300,
"stat": "Average",
"title": "EC2 CPU utilization",
"metrics": [
["AWS/EC2", "CPUUtilization", "InstanceId", "i-0123456789abcdef0"]
]
}
}
]
}
Save the JSON as dashboard.json, replace the example Region and instance ID, then create or update the dashboard:
aws cloudwatch put-dashboard --dashboard-name EC2-Overview --dashboard-body file://dashboard.json --region us-east-1
Choose a statistic that matches the metric
For network bytes, add a separate widget with Sum to see bytes per period; divide by the period in seconds to estimate average bytes per second. CPU is a percentage, so an Average or Maximum view is usually more interpretable than Sum. For filesystem alarms, graph the intended mount point and the exact agent dimensions. For EBS saturation or latency, use per-volume metrics with the relevant VolumeId, as described in the Amazon EBS CloudWatch metrics reference, rather than instance-store disk metrics.
Organize views for multiple instances
For an Auto Scaling group, EC2 metrics can use the AutoScalingGroupName dimension. EC2 detailed monitoring also makes the InstanceType and ImageId dimensions available for supported metrics; these group data across similar instances and do not identify one machine. For tag-based resource exploration, use CloudWatch Metrics Explorer where supported. Do not use a tag map or wildcard as though it were an AWS/EC2 metric dimension. Review AWS's Metrics Explorer guide and the EC2 dimension reference before designing fleet widgets.
Keep monitoring actionable and affordable
Start with signals tied to workload behavior
Use EC2 metrics to understand instance capacity and status, agent metrics for guest operating-system resources, and application metrics for user-visible health. No single CPU, memory, disk, or network threshold is a universal failure condition. Set alarm limits from historical workload data, service objectives, tested capacity, and the time operators or automation need to respond.
Reduce noise without hiding a real failure
Review alarm history and graphs before changing a threshold. Check for a mismatched namespace or dimension, a period shorter than the publishing interval, an unsuitable statistic, or a missing-data assumption that treats a quiet signal as failure. Use multiple breaching datapoints when brief spikes are harmless; use a faster condition only when the metric can support it and the response needs it.
Review monitoring costs before expanding collection
Detailed EC2 monitoring is charged per metric sent. CloudWatch agent metrics are custom metrics; collecting more measurements, mount points, or distinct dimension combinations can increase the number of metric series. Alarms, logs, dashboards, and high-resolution data can have separate charges. Estimate the metrics and dimensions you plan to publish, then check the current CloudWatch pricing page for your Region and usage. AWS pricing and free usage terms can change, so a fixed per-instance price is not reliable.
Summary
Start with the metrics EC2 already publishes, enable detailed monitoring only when one-minute EC2 data changes a decision, and install the CloudWatch agent for memory and filesystem signals. Build alarms from the metric's actual namespace, dimensions, unit, and publishing interval. Use status-check alarms for the failure type they measure, route notifications to an owner, and keep dashboards focused on workload decisions.