CloudWatch metrics: identity, retention, publishing, EMF and metric math

How CloudWatch metrics work for someone reading or publishing them — a metric is namespace + name + exact dimensions, retention by resolution (3 hours to 15 months), PutMetricData limits and visibility delays, the Embedded Metric Format for logging metrics from Lambda, metric math functions and their missing-data rules, and what each AWS/Lambda metric does and doesn't count.

markdownreferencev4QT04-VGV8stage: referencetrust: officialservice: cloudwatchinterface: anyCloudWatch metric dimensions identitymetric retention 15 monthshigh resolution 1 secondPutMetricData limitsmetric not showing ListMetrics 15 minutescustom metric namespace AWS reservedEmbedded Metric FormatEMF _aws CloudWatchMetricsEMF metrics missingmetric math syntaxFILLIFMETRICS()RATEANOMALY_DETECTION_BANDSEARCHdivision by zero metric mathLambda metricsErrors includes timeoutsThrottlesIteratorAgeConcurrentExecutionsClaimedAccountConcurrencyAsyncEventsDroppedpercentiles

Created 18 Oct 2026 · Modified 23 Oct 2026 · 4 versions

A metric is its namespace, its name and its exact set of dimensions. Errors with FunctionName=a and Errors with FunctionName=a, Resource=a:prod are two different metrics. CloudWatch doesn't add custom metrics up across dimensions for you, so query with exactly the dimensions you published.

Basics

  • Regional. A metric exists only in the Region it was published to.
  • Can't be deleted. A metric expires after 15 months without new data.
  • Retention by resolution (rolled up as it ages):
PeriodKept
Under 60 s (1-second, high-resolution custom metrics)3 hours
60 s15 days
300 s63 days
3600 s455 days (15 months)
  • Periods are 1, 5, 10, 30 or multiples of 60 seconds. The default is 60, and sub-minute periods only work on custom metrics stored at 1-second resolution.
  • Statistics: Sum, Average, Minimum, Maximum, SampleCount, percentiles (p99, up to ten decimals) and trimmed mean.
  • Percentiles need raw values, none of them negative.
  • Statistic sets give percentiles only in narrow cases (for example, SampleCount 1).
  • Units: default None. Points with different units are aggregated separately, so publish one unit consistently.

Publishing (PutMetricData)

LimitValue
Request1 MB (gzip accepted), up to 1,000 metrics
DimensionsUp to 30 per metric
Values / Counts arraysUp to 150 values per metric per request
TimestampsUp to 2 weeks in the past, 2 hours in the future
ValuesWithin ±2^360. No NaN or Infinity
Namespace1–255 characters; don't start with AWS/

Visibility delays:

  • A new metric can take up to 15 minutes to appear in ListMetrics (and so in the console's metric browser).
  • Data timestamped 3–24 hours ago can take up to 2 hours to become queryable; data older than 24 hours, 48 hours or more.
  • StorageResolution: 1 makes a high-resolution metric.

Errors: InvalidParameterValue, InvalidParameterCombination, MissingParameter (400) and InternalServiceError (500). The SDK names them …Exception; see reference/cloudwatch/errors.md.

Embedded Metric Format (metrics from log lines)

Write each log event as one JSON object that follows the specification, and CloudWatch extracts the metrics from it. AWS names three ways to send the events: the open-source EMF client libraries, the CloudWatch agent, or PutLogEvents. Because there's no PutMetricData call, the cloudwatch:PutMetricData permission shouldn't be needed (the hub's reading). From Lambda, the common approach is to write the object to stdout, as below. That path isn't described on the fetched pages (UNVERIFIED), so confirm the metric appears before you rely on it:

export function emitMetric(name: string, value: number, dims: Record<string, string>) {
  console.log(JSON.stringify({
    _aws: {
      Timestamp: Date.now(),                                   // milliseconds
      CloudWatchMetrics: [{
        Namespace: "orders",
        Dimensions: [Object.keys(dims)],                       // array of dimension sets
        Metrics: [{ Name: name, Unit: "Milliseconds", StorageResolution: 60 }],
      }],
    },
    ...dims,                                                   // dimension values: top level
    [name]: value,                                             // metric value: top level
  }));
}

emitMetric("checkoutLatency", 142, { service: "checkout", stage: "prod" });

Rules:

  • The whole log event must be the JSON object, with nothing before or after it.
  • Dimension keys and metric values must be top-level members, not nested.
  • Values are numbers or arrays of up to 100 numbers.
  • Up to 100 metric definitions per event and 30 keys per dimension set. Each dimension set becomes its own metric. Event size up to 1 MB. Timestamps from 14 days past to 2 hours future.

When EMF metrics don't appear:

  • Look in the AWS/Logs namespace, which counts extraction failures.
  • A bad namespace or name drops that metric; a bad dimension drops that dimension set.
  • An out-of-range value, an array over 100, or more than 100 definitions drops the whole event's metrics.
  • Delivery is at-least-once, so occasional duplicates are normal.

How Lambda's Text and JSON log formats interact with the "nothing before or after" rule isn't on the fetched pages. If metrics are missing, check the AWS/Logs failure counts first.

Metric math

  • IDs start with a lowercase letter (m1, errors). Functions are uppercase. The result must be a time series, so scalar functions go inside a bigger expression (m1 - AVG(m1)).
  • Functions:
  • METRICS() and METRICS("err") (by ID substring);
  • SUM, AVG, MIN, MAX, STDDEV;
  • FILL(m, 0 | REPEAT | LINEAR), IF(cond, a, b);
  • RATE, DIFF, DIFF_TIME, PERIOD;
  • ANOMALY_DETECTION_BAND(m, n) (default 2 standard deviations);
  • SEARCH(...), INSIGHT_RULE_METRIC, SERVICE_QUOTA.
  • Missing data: treated as 0 in arithmetic and comparisons. A division by zero drops that point.
  • Limits:
  • 500 metrics and expressions per graph;
  • no alarms on SEARCH;
  • anomaly detection on math can't use METRICS, SEARCH, more than 10 inputs, mixed periods, periods over an hour or high-resolution metrics.

AWS/Lambda metrics: what they count

MetricStatisticCountsDoesn't count
InvocationsSumEvery invocation, including those that errored (= billed requests)Throttled requests, other invocation errors
ErrorsSumFunction errors: thrown exceptions, timeouts, runtime and configuration errors. Timestamped at invoke timeThrottles
ThrottlesSumRequests refused with TooManyRequestsException—
DurationAvg, Max, pNNTime in your handlerCold-start init time
ConcurrentExecutionsMaxInstances processing events—
ClaimedAccountConcurrencyMaxRegional concurrency not available on demand (unreserved in use + reserved + provisioned)—
IteratorAgeMaxAge (ms) of the last record in a batch: DynamoDB, Kinesis, DocumentDB—
OffsetLagMaxKafka / MSK consumer lag—
AsyncEventAge / AsyncEventsDroppedMax / SumQueue time of async events / events dropped after max age or retries—
DeadLetterErrors, DestinationDeliveryFailuresSumFailed sends to a DLQ or destination (FIFO SQS and SNS destinations aren't supported)—

Error rate = Errors / Invocations (alarm recipe: guides/cloudwatch/create-alarms.md).

Read this document as markdown — the same bytes an agent receives.