CloudWatch custom metrics cost in 2026

Akal Cloud Updated 10 min read

Quick answer

A CloudWatch custom metric costs $0.30 a month in AWS's US East worked examples. That is the wrong unit to budget against. AWS bills one metric per unique combination of metric name and dimension values, not per metric name, so one line of instrumentation that attaches a request ID becomes thousands of billed metrics. At 100 requests a second that single metric bills as 360,000 metrics and costs $32,500 a month.

A CloudWatch custom metric costs $0.30 a month in AWS's own US East worked examples. That is the number everyone budgets against, and it is the wrong unit. AWS bills one metric per unique combination of metric name and dimension values, not per metric name, so one line of instrumentation that attaches a request ID becomes thousands of billed metrics. At 100 requests a second, that single metric bills as 360,000 metrics and costs $32,500 a month.

How much does one CloudWatch custom metric cost per month?

$0.30, falling to $0.10 and then $0.05 as volume grows. The CloudWatch pricing page renders its tier table in JavaScript, but Example 6 prices 255,000 metrics in prose: "First 10,000 custom metrics @$0.30 per metric = 10,000 * $0.30 = $3,000", then "10,001 to 250,000 custom metrics @$0.10 per metric = 240,000 * $0.10 = $24,000", then "250,001 to 255,000 custom metrics @0.05 per metric = 5000 * $0.05 = $250".

Tier (US East, from AWS's worked examples)Rate per metric-monthCost of filling the tier
First 10,000 metrics$0.30$3,000.00
Next 240,000 metrics$0.10$24,000.00
Next 750,000 metrics$0.05$37,500.00
Over 1,000,000 metricsnot stated in any prose examplesee the pricing table

The tiers are marginal, not retroactive, so 1,000,000 metrics cost $64,500 a month and not $50,000. The fourth tier's rate appears only in the JavaScript table, so we do not quote a number for it.

The charge is prorated. Example 8 prices S3 replication metrics that ran for part of the month: "First 10,000 custom metrics @$0.30 per metric = $0.30 * 8 (number of metrics) * 30 (metric hours per month) per 720 (hours per month) = $0.10 per month." One metric-hour is $0.30 divided by 720, or $0.000417. Hold that formula. It is what makes the cardinality arithmetic below work.

What counts as one custom metric in CloudWatch billing?

Not one metric name. The CloudWatch FAQ defines the billable object loosely: "A custom metric is any metric you provide to Amazon CloudWatch." The CloudWatch concepts page tightens it. A dimension "is a name/value pair that is part of the identity of a metric. You can assign up to 30 dimensions to a metric", so "whenever you add a unique name/value pair to one of your metrics, you are creating a new variation of that metric."

The pricing page states the billing consequence in one sentence, and the concepts page repeats it word for word: "CloudWatch treats each unique combination of dimensions as a separate metric, even if the metrics have the same metric name."

So RequestLatency tagged Service=checkout and RequestLatency tagged Service=search are two billed metrics, and there is no free rollup: "CloudWatch does not aggregate across dimensions for your custom metrics." The total across services is a third.

How much does a high-cardinality dimension cost in CloudWatch?

The multiplier is the number of distinct dimension values seen per hour, which falls straight out of AWS's proration formula. Take the easy case first, as a hypothetical at the $0.30 tier rate. One metric name with an InstanceId dimension across 500 hosts that run all month is 500 billed metrics, $150.00 a month, against $0.30 for the same metric published without the dimension.

Now the case AWS itself warns about. A requestId dimension produces a value that is never seen again, so each combination bills one metric-hour, 1/720 of a metric-month, by Example 8's formula. The month's distinct metric count is astronomical and the billed quantity is not: it collapses to the number of distinct IDs per hour. All rows below are hypothetical, computed at the rates quoted above.

Request rate, one requestId dimensionDistinct metrics created in a 720-hour monthBillable metric-monthsMonthly metric charge
No requestId dimension at all11$0.30
1,000 requests per hour720,0001,000$300.00
10 requests per second25,920,00036,000$5,600.00
100 requests per second259,200,000360,000$32,500.00

One dimension, 108,333 times the cost. The same shape applies to a session ID, a trace ID, a customer ID or a Kubernetes pod name: anything whose value set churns. The CloudWatch cost analysis guide gives the same advice in reverse: "avoid creating metrics based on high-cardinality dimensions. This way, CloudWatch doesn't create a custom metric for each unique dimension combination."

One caveat we cannot resolve from AWS's pages. Example 8 applies a tier rate to a prorated quantity, so the table assumes the tier is applied to billable metric-months and not to the raw count of distinct metrics. AWS does not say which. If it is the raw count, a churning dimension reaches the cheaper tiers sooner and these figures are an upper bound.

Do CloudWatch custom metrics keep costing money after you stop publishing?

No, and it is the one piece of good news in the model. The pricing page is explicit: "All custom metrics and Detailed Monitoring charges are prorated by the hour and charges are incurred only when metrics are sent to CloudWatch in a given hour." The cost analysis guide agrees: "All custom metrics are prorated by the hour. They're metered only when they're sent to CloudWatch."

So a cardinality accident stops billing the hour you stop publishing. It does not stop existing. The FAQ is blunt: "CloudWatch does not support metric deletion. Metrics expire based on the retention schedules described above." Those run to fifteen months: "Data points with a period of 3600 seconds (1 hour) are available for 455 days (15 months)". They vanish from the console long before they vanish from storage, because "Metrics that have not had any new data points in the past two weeks do not appear in the console."

There is no switch, either. The publish custom metrics guide says what stopping means: "CloudWatch doesn't pull metrics from applications, it only receives what is pushed to it, so to stop publishing your metrics you must stop them at the source." So the bill runs until a deploy lands.

How much do PutMetricData and GetMetricData requests cost in CloudWatch?

$0.01 per 1,000 requests, and the pricing page contradicts itself about it by a factor of 1,000. The prose above the tier table says: "In addition to the metric storage charge, metrics published via the PutMetricData service incur an additional charge of $0.01/M requests." Example 6, on the same page, computes it as "1,000,001 to 440,640,000 API requests = 439,640,000/1,000 * $0.01 = $4,396.40".

That is a thousand times the rate the prose states. At the prose rate the example's own API line would be $4.40, not $4,396.40, and its total of $31,646.40 would not add up. The GetMetricData reference breaks the tie for the retrieval side, stating a flat rate per 1,000 metrics requested. Budget at $0.01 per 1,000.

Which produces a break-even AWS never publishes. One request costs $0.00001, so 30,000 requests cost the same as one metric-month at $0.30. A 30-day month is 2,592,000 seconds, so any single metric published more often than once every 86.4 seconds costs more in API charges than in metric charges. Once a minute, unbatched, is $0.432 in requests against $0.30 for the metric. Once a second is $25.92 against $0.30.

Meter (US East, from AWS's worked examples)RateFree allowance
Custom metric, first tier$0.30 per metric-month10 metrics
PutMetricData request$0.01 per 1,0001 million API requests
GetMetricData$0.01 per 1,000 metrics requestednone, always charged
Standard-resolution alarm metric$0.10 per month10 alarm metrics
High-resolution alarm metric$0.30 per monthnone

The escape is batching. The PutMetricData API reference states that "Each request is also limited to no more than 1000 different metrics", and a request "is limited to 1 MB in size for HTTP POST requests. You can send a payload compressed by gzip." Publishing 100 metrics a second as 100 separate calls costs $2,582.00 a month. Packed 1,000 per call, the same volume is 259,200 requests, inside the free million. The request charge is a batching problem, not a volume problem.

Are high-resolution CloudWatch custom metrics more expensive?

Not to store, and that answer is a trap. The FAQ is unambiguous: "No, high-resolution custom metrics are priced in the same manner as standard one-minute custom metrics." Sixty times the data points, same $0.30.

The meters around it are where the money goes. High resolution means calling PutMetricData sixty times as often, at the rate above, unless you batch. And the alarm rate triples. The pricing page defines the class, "High-resolution alarms are alarms with an evaluation period of less than 60 seconds (for example 10 or 30 seconds)", and its worked examples price the two side by side: "4 alarms × $0.30 per alarm = $1.20" for high resolution against "$0.10 * 3 standard resolution metrics per alarm = $0.30 per month" for standard.

Anomaly detection alarms compound it. They "incur costs for each metric that you list in the alarm metric expression, plus two additional alarm-metric costs to account for the upper and lower band metrics generated by the anomaly detection model", so one anomaly alarm on one metric bills as three. The cost-side equivalent is in AWS Budgets versus Cost Anomaly Detection.

Does the embedded metric format make CloudWatch custom metrics cheaper?

Not by itself. The embedded metric format is widely believed to move the charge from metrics to logs. It adds one. The cost analysis guide itemises all three: "Embedded metrics generate costs by the number of logs ingested, number of logs archived, and number of custom metrics generated." EMF metrics bill as operation MetricStorage:AWS/Logs-EMF, at the same per-metric rate as anything from PutMetricData, with log ingestion on top.

EMF also makes a cardinality accident easier to have, not harder. Its own page warns that "the embedded metric format will by design create a custom metric corresponding to each unique dimension combination", naming requestId as the example, and the EMF specification makes it concrete: "Every DimensionSet used creates a new metric in CloudWatch."

The lever is one line of the same specification: "The root node MAY contain any other members that are not included in the above requirements." Root-node fields not named in a DimensionSet stay in the log event and never become metrics. Put the request ID and the trace ID in the JSON as plain properties, keep the DimensionSet to the two or three low-cardinality fields you alarm on, and query the rest with Logs Insights. That trades an unbounded metric charge for a bounded log charge: what CloudWatch Logs ingestion and storage cost covers the Infrequent Access class and the Logs Insights scan charge, and Lambda cold start cost covers the runtime side of the function usually emitting them.

What is free in CloudWatch metrics, alarms and API requests?

Ten of each, plus a million requests. The free tier lists "10 Metrics (of Custom Metrics and Detailed Monitoring Metrics)", "1 Million API requests (not including GetMetricData, GetInsightRuleReport and GetMetricWidgetImage: these 3 operations are always charged)", "3 Custom Dashboards referencing up to 50 metrics each per month" and "10 Alarm metrics" restricted to standard-resolution alarms that list metrics directly.

Note which side the exclusions fall on: publishing is free for the first million calls, reading never is. The Metrics Insights quotas then cap what you can see. "A single query can process no more than 10,000 metrics", so in an account where one dimension has exploded, one metric name reaches that ceiling by itself.

To find the damage on the bill, the cost analysis guide names the line items. All of them bill as usage type MetricMonitorUsage, separated by operation: MetricStorage for custom metrics, MetricStorage:AWS/{Service} for detailed monitoring, MetricStorage:AWS/Logs-EMF for EMF and MetricStorage:AWS/CloudWatchLogs for log group metric filters. Those strings separate instrumentation you wrote from monitoring you switched on, and only the Cost and Usage Report carries them. Cost Explorer versus the CUR covers why the console cannot show that breakdown, and partition projection for CUR in Athena covers querying it without a crawler.

When does OpenTelemetry metric pricing beat per-metric pricing in CloudWatch?

Below roughly one data point every 1.2 to 2.4 seconds per series, a crossover AWS does not publish. The pricing page states the model: "Publishing OpenTelemetry metrics to CloudWatch is charged at $0.50 per GB ingested. This flat rate includes 15 months of storage with no separate charges for API calls, metric storage, or number of unique metric series." It also gives the byte size needed to convert: "A typical data point with 10-15 attributes is 300-600 bytes."

So work out how many data points $0.30 of ingestion buys. At AWS's own convention of 1,048,576 KB per GB, $0.30 buys 0.60 GB: 2,147,484 data points at 300 bytes each, or 1,073,742 at 600 bytes. Across a 2,592,000 second month that is one data point every 1.21 to 2.41 seconds. Publish slower and the per-GB model beats the $0.30 a Classic series costs, before the PutMetricData charges Classic adds and OTel does not. One series at one-minute resolution is $0.006 to $0.012 on OTel against $0.30 on Classic.

The OTel metrics pricing page makes the cardinality point directly: "You pay based on the volume of data ingested, not the number of unique metric series", and "Unlike Classic pricing, there is no cost per unique metric name or label combination". Its comparison table calls Classic's high-cardinality cost "Expensive — each unique dimension combination is a separate billable metric". Bytes are not free, so it still says to "Drop high-cardinality labels that you don't query (for example, request IDs) at the collector level". But the failure mode is linear rather than multiplicative.

That is the same choice one layer up. Container Insights is priced per metric on the classic path and per GB on the OTel path, at cluster scale, in what Container Insights costs on EKS and ECS. The decision that moves a CloudWatch bill is not which dashboard to delete. It is which field becomes a dimension.

Share LinkedIn X Hacker News Reddit

See this on your own bill

Akal Cloud connects in about two minutes and shows the same numbers against your real AWS accounts.

Get started on AWS Marketplace

Related reading