Subchapter 37.36
references/cloudwatch/metrics.mdMarkdown7 KBView on GitHub
Publishing, querying, and managing custom metrics — EMF, PutMetricData, metric filters, and retention.
| Criteria | EMF | PutMetricData |
|---|---|---|
| Latency impact | None (async via logs) | Synchronous API call |
| Log correlation | Yes — Metrics + logs in same event | No — Separate |
| Max metrics per call | 100 per MetricDirective | 1,000 MetricDatum per request |
| High-resolution | Yes — StorageResolution=1 | Yes — StorageResolution=1 |
| Cost model | Log ingestion pricing | Per-metric API charges |
| Best for | Lambda, containers | Batch jobs, custom agents |
Default recommendation: Use EMF for Lambda and containerized workloads. Use PutMetricData for batch jobs or when you need synchronous confirmation.
{
"_aws": {
"Timestamp": 1574109732004,
"CloudWatchMetrics": [{
"Namespace": "MyService",
"Dimensions": [["ServiceName", "Environment"]],
"Metrics": [
{ "Name": "Latency", "Unit": "Milliseconds", "StorageResolution": 60 },
{ "Name": "RequestCount", "Unit": "Count" }
]
}]
},
"ServiceName": "OrderService",
"Environment": "Production",
"Latency": 100,
"RequestCount": 1,
"RequestId": "abc-123"
}AWS/Timestamp in _aws is required per the EMF spec and JSON schema (milliseconds since epoch). In practice, if omitted, CloudWatch uses the log event’s ingestion time — but explicitly setting it is recommended to avoid clock-skew issues.For Lambda/containers, use a library that handles EMF serialization (e.g., Lambda Powertools Metrics, aws-embedded-metrics). These libraries manage the _aws metadata block, dimension limits, and metric flushing automatically.
AWS/Instead of publishing individual data points, aggregate into StatisticSets:
{
"MetricName": "Latency",
"StatisticValues": {
"SampleCount": 100,
"Sum": 5000,
"Minimum": 10,
"Maximum": 200
},
"Unit": "Milliseconds"
}Reduces API calls and cost.
Extract metrics from log events automatically.
{ $.statusCode >= 500 }Publishes a metric with value 1 for each matching log event.
| Data point period | Available for | Then aggregated to |
|---|---|---|
| < 60s (high-res) | 3 hours | 1-minute |
| 60s (1 min) | 15 days | 5-minute |
| 300s (5 min) | 63 days | 1-hour |
| 3600s (1 hr) | 455 days (15 months) | — |
Key insight: You cannot query 1-minute data from 2 months ago. It has been automatically aggregated to 5-minute resolution. High-resolution (1-second) data is only available for 3 hours.
OTel metrics: Only 30 days retention (public preview) — significantly shorter than traditional CloudWatch metrics (15 months).
Note: Each unique dimension combination = separate metric = separate cost.
requestId, userId, sessionId as dimensions — creates millions of metrics{InstanceId, InstanceType} and expect to query by InstanceId alone — must publish both combinations separatelyServiceName, Environment, Operation, StatusCodeSEARCH function for cross-dimension queriesCombine metrics using expressions in alarms and dashboards.
SUM, AVG, MIN, MAX, STDDEV, PERIOD, SEARCH, IF, FILL, ANOMALY_DETECTION_BAND
errors * 100 / invocationsSEARCH('{AWS/Lambda,FunctionName} MetricName="Errors"', 'Sum', 300)Automatically includes new functions matching the pattern — useful in dashboards and graphs (SEARCH cannot be used in alarms).
FILL can permanently stick an alarm: If a metric is published with slight delay, FILL replaces the missing latest point with the fill value, keeping the alarm in a fixed state. Use M-of-N alarms instead.RATE on sparse metrics is unpredictable: The evaluation range varies, causing inconsistent rate calculations. Avoid RATE in alarms on metrics that don’t publish every period.ANOMALY_DETECTION_BAND per expression, cannot combine with METRICS() or SEARCH, cannot use high-resolution metrics. See CloudWatch metric math docs (opens in a new tab) for full list.AWS/Logs namespace publishes EMFValidationErrors and EMFParsingErrors metrics. Check these if metrics aren’t appearing."A.a" matches { "A.a": 1 }, NOT { "A": { "a": 1 } }. Metric and dimension values must be on the root node.Dimensions: [["Service"], ["Service", "Operation"]] creates 2 metrics per data point, not 1. Libraries like Powertools do this by default.