CloudWatch metric streams that may be streaming namespaces nobody uses
What does ZopNight detect here?
CloudWatch metric streams bill $0.003 per 1,000 metric updates in us-east-1, plus Amazon Data Firehose delivery. ZopNight lists running streams but raises no dollar finding, because the `MetricUpdate` metric is split by `MetricStreamName` only, with no namespace dimension, so it cannot show how much of a stream's volume comes from each namespace you might exclude.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-177 |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Threshold | active, priced metric stream |
| Source | ZopNight |
| Permissions used | cloudwatch:ListMetricStreams · cloudwatch:GetMetricStream · cloudwatch:GetMetricStatistics |
Where it applies
Streams bill per metric update, not per stream
Metric streams push CloudWatch metrics continuously to Amazon Data Firehose, for delivery to S3 or to a partner such as Datadog, Dynatrace, New Relic or Splunk. With no filters, a stream sends every metric in the account and Region, including new ones as they appear.
CloudWatch pricing charges per metric update. One update carries the four default statistics (minimum, maximum, sample count and sum), and each extra five statistics you request for a metric count as another update. The AWS price list for US East (N. Virginia) sets the rate at $0.003 per 1,000 metric updates, and Firehose charges for delivery on top. A stream left on “all metrics” when the tool on the other end only charts EC2 and RDS pays for every other namespace too.
Checking what each stream sends
aws cloudwatch list-metric-streams \ --query 'Entries[].[Name,State,OutputFormat,FirehoseArn]' --output table
aws cloudwatch get-metric-stream --name my-stream \ --query '[IncludeFilters,ExcludeFilters,StatisticsConfigurations]'Empty include and exclude lists mean the stream sends everything. The stream’s own volume is in the
MetricUpdate metric in the AWS/CloudWatch/MetricStreams namespace, which is emitted only while
the stream is running.
What would have to be measured
The only lever is removing namespaces the destination does not use, so a real saving is the
stream’s monthly cost multiplied by the share of its updates those namespaces produce. ZopNight can
price a running stream, and the stream’s total update count can be read. The share cannot.
MetricUpdate is published per stream and as an account total,
with a MetricStreamName dimension and no namespace split, and the stream configuration lists the
namespaces without any counts.
Why this stays advisory permanently
Splitting the total by a guessed ratio would invent the number the recommendation depends on, so the rule does not produce a finding for any stream. This is not waiting on a missing data feed: AWS does not publish the breakdown. Use the steps below to size the saving yourself.
Estimating the saving by hand
saving = stream monthly cost x (updates from excludable namespaces / total updates)To estimate the fraction, count the metrics per namespace with aws cloudwatch list-metrics --namespace AWS/EC2 and similar, multiply by the updates each sends per month, and compare with the
MetricUpdate total.
Cutting a stream down to what is used
- Ask the owners of the destination which namespaces their dashboards and alerts read.
- Add filters with
aws cloudwatch put-metric-stream, passing the same name, Firehose ARN, role ARN and output format. A stream can have up to 1,000 filters, but only include filters or only exclude filters, not both. - Drop additional statistics you do not chart, since each extra five count as another update.
- Delete the stream with
aws cloudwatch delete-metric-streamif nothing downstream reads it.