AWS for DevOps — CloudWatch Metrics & Alarms
10.1 — CloudWatch Metrics & Alarms
Metrics
Every AWS service emits metrics to CloudWatch automatically. You can also publish custom metrics from your applications.
| Service | Key Metrics |
|---|---|
| EC2 | CPUUtilization, NetworkIn/Out, StatusCheckFailed |
| ALB | RequestCount, TargetResponseTime, HTTPCode_Target_5XX_Count |
| ECS | CPUUtilization, MemoryUtilization |
| Lambda | Invocations, Duration, Errors, Throttles, ConcurrentExecutions |
| RDS | CPUUtilization, FreeStorageSpace, DatabaseConnections |
Metric Anatomy
| Component | Example |
|---|---|
| Namespace | AWS/EC2, AWS/Lambda, Custom/MyApp |
| Metric Name | CPUUtilization |
| Dimensions | InstanceId=i-abc123 |
| Period | 60 seconds, 300 seconds |
| Statistic | Average, Sum, Minimum, Maximum, p99 |
Viewing Metrics
# List metrics for EC2
$ aws cloudwatch list-metrics --namespace AWS/EC2 --metric-name CPUUtilization \
--query 'Metrics[0:3].Dimensions'
# Get metric data
$ aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-abc123 \
--start-time 2026-03-30T00:00:00Z \
--end-time 2026-03-30T12:00:00Z \
--period 300 \
--statistics Average Maximum
{
"Datapoints": [
{ "Timestamp": "2026-03-30T10:00:00Z", "Average": 45.2, "Maximum": 78.5 },
{ "Timestamp": "2026-03-30T10:05:00Z", "Average": 42.1, "Maximum": 65.3 }
]
}
Custom Metrics
# Publish a custom metric
$ aws cloudwatch put-metric-data \
--namespace Custom/MyApp \
--metric-name OrdersProcessed \
--value 42 \
--unit Count \
--dimensions Environment=production,Service=order-api
Alarms
Alarms watch a metric and trigger actions when thresholds are breached.
Metric: CPUUtilization
│
▼
Alarm evaluates every 60 seconds
│
┌────┴────────────────────┐
│ │
OK (< 80%) ALARM (≥ 80% for 3 periods)
│ │
(no action) SNS → email/Slack
Auto Scaling → add instances
Alarm States
| State | Meaning |
|---|---|
OK |
Metric is within the threshold |
ALARM |
Metric has breached the threshold |
INSUFFICIENT_DATA |
Not enough data to evaluate |
Creating an Alarm
$ aws cloudwatch put-metric-alarm \
--alarm-name high-cpu-production \
--alarm-description "CPU above 80% for 3 consecutive periods" \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-abc123 \
--statistic Average \
--period 300 \
--evaluation-periods 3 \
--threshold 80 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions arn:aws:sns:ap-south-1:123456789012:ops-alerts \
--ok-actions arn:aws:sns:ap-south-1:123456789012:ops-alerts \
--treat-missing-data notBreaching
| Parameter | Value | Why |
|---|---|---|
period: 300 |
5 minutes per datapoint | Avoids false alarms from short spikes |
evaluation-periods: 3 |
3 consecutive breaches | Only alarm on sustained issues |
treat-missing-data: notBreaching |
Missing data = OK | Prevents alarms during maintenance |
Composite Alarms
Combine multiple alarms with AND/OR logic:
$ aws cloudwatch put-composite-alarm \
--alarm-name critical-service-alarm \
--alarm-rule 'ALARM("high-cpu-production") AND ALARM("high-error-rate")' \
--alarm-actions arn:aws:sns:ap-south-1:123456789012:critical-alerts
This fires only when both CPU is high AND error rate is high — reducing false positives.
Anomaly Detection
CloudWatch can learn normal patterns and alarm on anomalies:
$ aws cloudwatch put-anomaly-detector \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-abc123 \
--stat Average
Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
| Single evaluation period | False alarms from brief spikes | Use 3+ evaluation periods |
treat-missing-data: breaching |
Alarms fire during maintenance | Use notBreaching or missing |
No ok-actions |
Never know when issues resolve | Send OK notifications too |
| Alarming on average only | Hides spikes (average can be low while p99 is terrible) | Add p99/max alarms for latency |
Quick Reference
| Task | Command |
|---|---|
| List metrics | aws cloudwatch list-metrics --namespace NAMESPACE |
| Get metric data | aws cloudwatch get-metric-statistics --namespace NS --metric-name NAME ... |
| Create alarm | aws cloudwatch put-metric-alarm --alarm-name NAME --threshold VAL ... |
| Describe alarms | aws cloudwatch describe-alarms --alarm-names NAME |
| Delete alarm | aws cloudwatch delete-alarms --alarm-names NAME |
| Put custom metric | aws cloudwatch put-metric-data --namespace NS --metric-name NAME --value VAL |
Next → CloudWatch Logs