Optimize

Enabling EC2 Memory Metrics for Accurate Rightsizing

Install and verify the CloudWatch agent so DigiUsher can read EC2 memory utilisation, and confirm DigiUsher's read-only IAM role has permission to read those metrics. Without memory data, rightsizing recommendations are based on CPU, network, and disk alone and may suggest more downsizing than a memory-aware analysis would.

Amazon EC2 publishes CPU, network, and disk metrics to CloudWatch by default, but it does not publish memory. Memory is an OS-level metric the hypervisor cannot see, so it only becomes available once the CloudWatch agent is installed on the instance. Until then, DigiUsher's recommendation engine has no memory signal and sizes instances from CPU, network, and disk alone — which can surface downsizing recommendations that go further than a memory-aware analysis would support.

This page walks through the full path: install the agent, configure it to emit memory, verify the data lands in CloudWatch, confirm DigiUsher's read-only role can read it, and confirm memory then appears in DigiUsher.

Time to accurate recommendations

After memory starts flowing, allow 15 full days of history (roughly 360 hours in a 30-day window) before treating memory-based rightsizing as statistically significant. Recommendations refine as history accrues.

Prerequisites

  • An IAM role you can attach to the instance (or an existing instance profile you can edit).
  • SSM access to the instance, or shell access to run the installer manually.
  • The DigiUsher AWS data source already connected. See Connecting an AWS account and the Permissions Reference.

Setup

Step 1 — Give the instance permission to publish metrics

The agent needs its own permission to write metrics. Attach the AWS-managed CloudWatchAgentServerPolicy to the instance's IAM role (instance profile). If you plan to store the agent config in SSM Parameter Store, also add AmazonSSMManagedInstanceCore.

This is separate from DigiUsher's permissions

This role lets the agent write to CloudWatch (Steps 1–5). DigiUsher's role lets DigiUsher read from CloudWatch (Step 6).

Step 2 — Install the CloudWatch agent

Option A — SSM (recommended for fleets). Use the AWS-ConfigureAWSPackage document to install AmazonCloudWatchAgent across instances without shelling in.

Option B — Manual (single instance, Amazon Linux 2 / 2023):

sudo yum install -y amazon-cloudwatch-agent

For Ubuntu/Debian, download the .deb for your architecture from the AWS-hosted package location and install with dpkg -i. Windows uses the MSI package.

Step 3 — Configure the agent to emit memory

Create an agent config that collects mem_used_percent and, critically, appends the InstanceId dimension under the CWAgent namespace. DigiUsher (and AWS Compute Optimizer) match memory to an instance via this dimension — if it is missing or renamed, the memory data cannot be associated with the instance.

/opt/aws/amazon-cloudwatch-agent/etc/config.json:

{
  "metrics": {
    "namespace": "CWAgent",
    "append_dimensions": {
      "InstanceId": "${aws:InstanceId}"
    },
    "metrics_collected": {
      "mem": {
        "measurement": ["mem_used_percent"],
        "metrics_collection_interval": 60
      },
      "disk": {
        "measurement": ["used_percent"],
        "resources": ["*"],
        "metrics_collection_interval": 60
      }
    }
  }
}

Windows uses Available MBytes (preferred) under the same CWAgent namespace with the InstanceId dimension appended, following the same structure as the Linux config.

Names are case-sensitive

Namespace and metric names are case-sensitive — use CWAgent and mem_used_percent exactly.

Step 4 — Start the agent and confirm it is running

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config -m ec2 -s \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json

# Confirm status is "running"
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status

A healthy result reports "status": "running".

Step 5 — Verify the metric is actually in CloudWatch

Don't assume — confirm the data point exists. In the CloudWatch console, open Metrics → All metrics → CWAgent → InstanceId and look for mem_used_percent for your instance.

Or via CLI (replace region and instance id):

# Does the metric exist for this instance?
aws cloudwatch list-metrics \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
  --region us-east-1

# Are data points landing?
aws cloudwatch get-metric-statistics \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
  --start-time 2026-07-13T00:00:00Z \
  --end-time 2026-07-14T00:00:00Z \
  --period 3600 --statistics Average Maximum \
  --region us-east-1 --output table

If list-metrics returns nothing, recheck the namespace, the InstanceId dimension, and that the agent is running (Steps 3–4).

Step 6 — Confirm DigiUsher's IAM role can read the metric

DigiUsher reads metrics with a read-only role that includes cloudwatch:Get* and cloudwatch:List* (covering ListMetrics, GetMetricData, and GetMetricStatistics). Memory metrics live in the same CWAgent namespace DigiUsher already reads for other CloudWatch data, so no new permission is normally required — but verify, so we never ship half-baked recommendations on the assumption that access exists.

  1. Confirm the DigiUsher role is attached to the account that owns the instance — see the Permissions Reference.
  2. Confirm the read-only policy on that role includes cloudwatch:ListMetrics, cloudwatch:GetMetricData, and cloudwatch:GetMetricStatistics (or the cloudwatch:Get* / cloudwatch:List* wildcards).
  3. Validate from the role's perspective. Assuming the DigiUsher read role, the same list-metrics call from Step 5 must return mem_used_percent. If it returns results, DigiUsher can read it:
aws sts assume-role \
  --role-arn arn:aws:iam::<ACCOUNT_ID>:role/<DigiUsher-ReadOnly-Role> \
  --role-session-name du-mem-check
# then, with the returned temporary credentials, re-run the Step 5 list-metrics call

If the metric is visible in the console (Step 5) but absent under the DigiUsher role, the gap is IAM — fix the policy before expecting DigiUsher to reflect memory.

Step 7 — Confirm memory appears in DigiUsher

Once the metric is confirmed readable, memory begins flowing into DigiUsher on the next collection cycle. Rightsizing recommendations that previously ran on CPU/network/disk will begin to incorporate memory. Give it 15 days of history before relying on memory-based sizing, and expect recommendations to become more conservative where instances are memory-bound.

Rolling out across a fleet

  • Use SSM State Manager to keep the agent installed and configured on every instance, and to auto-configure new instances.
  • For Auto Scaling groups, bake the agent and config into the launch template / AMI so new instances publish memory from first boot.

Troubleshooting

SymptomLikely causeFix
No memory in DigiUsherAgent not installed / not runningSteps 2 and 4
Metric missing in CloudWatchInstanceId dimension missing or renamed; wrong namespaceStep 3 — use CWAgent + InstanceId exactly
Metric in console but not in DigiUsherDigiUsher role missing read access or not on this accountStep 6
"Insufficient data" / recommendation unchangedFewer than 15 days of memory historyWait out the collection window (Step 7)
Custom-metric charges appear on the billCloudWatch bills custom metrics by storage + APIExpected; collect only the metrics you need

Questions? support@digiusher.com