2026-08-01 to 2026-08-30, a 30-day window; monthly figures scale it to a 30.4-day month
Accounts
2 in scope
Findings
9
1 What we are willing to claim
Every finding in this report carries a confidence rating. Only findings the data supports are added to the recoverable total. The rest are printed in full and left out of the number, because a figure that does not survive a skeptical engineer is worth less than no figure at all.
$100k
recoverable per month, proven and likely findings only
$1.20M
recoverable per year at the same run rate
$213k
observed but not claimed, excluded from the figures to the left
Exact totals before rounding: PROVEN $1,976.00 plus LIKELY $98,125.05 is $100,101.05 recoverable per month, the sum of the recoverable figures on the findings below. UNPROVEN is $213,121.10 per month observed and not claimed. Its findings describe some of the same machines, so each machine is counted once, and none of it is in the recoverable total.
The hatched segment is money we are not claiming. It is shown at the same scale as the rest so the proportion is visible rather than described.
The proven band is thin, and that is the finding rather than an apology for it. Billing data on its own settles only what it records directly, and that is a short list. Every dollar above the proven line rests on an assumption printed beside the finding it belongs to, in a sentence you can read and refuse, and the figure goes with it if you do. Widening this band takes more measurement, not more confidence.
Total amortized spend across the period was $315k, of which $306k was GPU compute. (Illustrative figures from a synthetic specimen.) Amortized cost is used throughout, not unblended cost: AWS writes an unblended cost of zero on reserved-instance-covered line items, so a ranking by unblended cost makes the most expensive machine in an account disappear.
Dollar figures are at list price, before any negotiated discount the client holds: each usage line is priced from the export's gross cost columns. Pricing basis GROSS_AMORTIZED_LIST.
2 How to read a finding
PROVEN
The evidence covers the whole period, so there is no assumption to accept or reject. Two routes reach it: a commitment reconciled against a closed billing period, and cluster allocation sampled across the period rather than read once.
LIKELY
The billing data proves the cost. The waste follows from one stated assumption, printed with the finding, which you can accept or reject line by line.
UNPROVEN
There is a cost and a suspicion. The data that would settle it does not exist yet. These dollars are listed and then excluded from the recoverable total.
3 Findings
PROVEN
$1,976 per month recoverable across 1 finding, after machines named by more than one finding are counted once.
Commitment purchased and not consumed: $1,216/mo of Reserved Instance capacity and $760/mo of Savings Plan commitment
PROVENvalidation: synthetic fixture
$1,976
observed per month
$1,976
recoverable per month
2
resources
2/5
disruption to change
What to do.Sell unused Standard RIs on the Reserved Instance Marketplace where the term allows, or move workloads onto the committed instance families so the commitment is consumed. Savings Plan commitments cannot be sold; the recovery is to shift eligible usage onto them before the term ends.
resource
account
commitment
unused $ / month
arn:aws:ec2:us-east-1:ri/r-abc
111111111111
RIFee
$1,216
arn:aws:savingsplans::sp/sp-xyz
111111111111
SavingsPlanRecurringFee
$760
LIKELY
$98k per month recoverable across 5 findings, after machines named by more than one finding are counted once.
23 of 63 provisioned GPUs had no pod requesting them when the cluster was read, $60,432/mo
$60k
observed per month
$60k
recoverable per month
5
resources
2/5
disruption to change
Assumption.The cluster was read once, at 2026-09-01T00:00:00+00:00, and this figure applies that single reading to the whole billing period. One reading proves what was allocated at that instant and nothing about the hours either side of it. Sample allocation hourly for the period and whatever is observed becomes proven; until then this is an extrapolation and is rated as one.
What to do.Scale the affected node groups down to the number of GPUs actually requested. Where a node group exists for burst capacity, set its floor to zero and let the cluster autoscaler bring it up on a pending pod.
node
instance id
instance type
GPUs
GPUs requested
GPUs unrequested
node $ / month
unrequested $ / month
ip-10-0-001-10.ec2.internal
i-000000000000001001
p5.48xlarge
8
0
8
$40,157
$40,157
ip-10-0-000-10.ec2.internal
i-000000000000001000
p4d.24xlarge
8
0
8
$9,933
$9,933
ip-10-0-004-10.ec2.internal
i-000000000000001004
p4d.24xlarge
8
4
4
$16,020
$8,010
ip-10-0-003-10.ec2.internal
i-000000000000001003
g5.12xlarge
4
2
2
$2,980
$1,490
ip-10-0-002-10.ec2.internal
i-000000000000001002
g6e.xlarge
1
0
1
$842
$842
14 production GPU instances run continuously at on-demand rates, $153,949/mo
$154k
observed per month
$24k
recoverable per month
14
resources
3/5
disruption to change
Counted once.Taken on its own this finding identifies $33k per month. The figure above is what survives de-duplication and is what the recoverable total uses. The difference, $8,626 per month, sits on machines already claimed by gpu zero allocation, which are counted first because PROVEN findings go before LIKELY ones and the order of work decides within a rating. A machine is counted once however many findings describe it.
Assumption.The recoverable figure applies the one-year no-upfront Compute Savings Plan rate AWS publishes for each family (g5 21.25%, g6e 24.40%, p3 18.62%, p4d 23.92%, p5 21.25%), which comes to 21.48% across this set, and assumes the capacity is still wanted twelve months from now. The rates were read from the AWS Savings Plans and EC2 price lists for us-east-1, both published 2026-09-10; re-read them for another region, because they differ by region. If the workload is being migrated or retired inside the term, this finding does not apply.
What to do.Size a Compute Savings Plan to the observed floor of GPU usage, not to the peak. Commit to the level that has been running every day of the period and leave the rest on demand.
resource
account
instance type
accelerator
days always on
$ / month
i-000000000000001001
111111111111
p5.48xlarge
NVIDIA H100
30
$40,157
i-000000000000001005
111111111111
p5.48xlarge
NVIDIA H100
30
$40,157
i-000000000000001004
111111111111
p4d.24xlarge
NVIDIA A100
30
$16,020
i-000000000000001024
111111111111
p4d.24xlarge
NVIDIA A100
30
$16,020
i-00000000000000101b
111111111111
p3.8xlarge
NVIDIA V100
30
$8,930
i-00000000000000101d
111111111111
p3.8xlarge
NVIDIA V100
30
$8,930
i-000000000000001007
111111111111
g5.12xlarge
NVIDIA A10G
30
$4,138
i-00000000000000101f
111111111111
g5.12xlarge
NVIDIA A10G
30
$4,138
i-000000000000001023
111111111111
g5.12xlarge
NVIDIA A10G
30
$4,138
i-000000000000001027
111111111111
g5.12xlarge
NVIDIA A10G
30
$4,138
i-00000000000000101a
111111111111
p3.2xlarge
NVIDIA V100
30
$2,233
i-00000000000000101c
111111111111
p3.2xlarge
NVIDIA V100
30
$2,233
i-00000000000000101e
111111111111
g6e.xlarge
NVIDIA L40S
30
$1,358
i-000000000000001022
111111111111
g6e.xlarge
NVIDIA L40S
30
$1,358
9 untagged instances read as non-production and run continuously, $11,916/mo
$12k
observed per month
$8,369
recoverable per month
9
resources
2/5
disruption to change
Assumption.These resources carry no Environment tag. Each is classified from its account, its name, or its instance family, and the signals are listed per resource below. The finding holds if the client confirms the classification; strike any row that is wrong and the total falls by that row's cost. The recovery then carries the same working-week assumption as the tagged finding above. It treats a 50-hour working week as the time these machines are needed, which leaves 118 of the 168 hours in a week recoverable by scheduling, or 70.2% of the line. A different working pattern moves the figure in proportion, so confirm the hours and rescale. A machine genuinely needed around the clock recovers nothing here, whatever its tag says.
What to do.Confirm the classification, tag the resources so this stops being an inference, then schedule them off outside working hours.
resource
account
instance type
gpu
days always on
$ / month
why it was classified this way
i-00000000000000100e
111111111111
g4dn.12xlarge
yes
30
$2,854
Name tag contains 'dev'
i-000000000000001011
111111111111
g4dn.12xlarge
yes
30
$2,854
Name tag contains 'dev'
i-000000000000001014
222222222222
g4dn.12xlarge
yes
30
$2,854
account name contains 'sandbox'
i-000000000000001010
111111111111
g5.xlarge
yes
30
$734
Name tag contains 'dev'; single-accelerator g5 instance, the shape of a development box
i-000000000000001013
222222222222
g5.xlarge
yes
30
$734
account name contains 'sandbox'; single-accelerator g5 instance, the shape of a development box
i-000000000000001016
111111111111
g5.xlarge
yes
30
$734
Name tag contains 'qa'; single-accelerator g5 instance, the shape of a development box
i-00000000000000100f
111111111111
g4dn.xlarge
yes
30
$384
Name tag contains 'dev'; single-accelerator g4dn instance, the shape of a development box
i-000000000000001012
222222222222
g4dn.xlarge
yes
30
$384
account name contains 'sandbox'; single-accelerator g4dn instance, the shape of a development box
i-000000000000001015
111111111111
g4dn.xlarge
yes
30
$384
Name tag contains 'qa'; single-accelerator g4dn instance, the shape of a development box
10 tagged non-production instances run continuously, $6,495/mo, $4,706/mo of it GPU
$6,495
observed per month
$4,562
recoverable per month
10
resources
2/5
disruption to change
Assumption.The cost is read straight from the bill and the Environment tag is the client's own, so neither is in question. The recovery is. It treats a 50-hour working week as the time these machines are needed, which leaves 118 of the 168 hours in a week recoverable by scheduling, or 70.2% of the line. A different working pattern moves the figure in proportion, so confirm the hours and rescale. A machine genuinely needed around the clock recovers nothing here, whatever its tag says.
What to do.Stop non-production instances outside working hours with an EventBridge schedule or an autoscaler floor of zero. GPU instances should be stopped rather than resized, because the accelerator is the entire cost.
resource
account
instance type
gpu
days always on
$ / month
why it was classified this way
i-00000000000000100b
111111111111
g4dn.12xlarge
yes
30
$2,854
Environment tag = dev
i-00000000000000100a
111111111111
g5.xlarge
yes
30
$734
Environment tag = dev
i-00000000000000100d
111111111111
g5.xlarge
yes
30
$734
Environment tag = dev
i-000000000000009007
111111111111
c5.9xlarge
no
30
$692
Environment tag = dev
i-00000000000000100c
111111111111
g4dn.xlarge
yes
30
$384
Environment tag = dev
i-000000000000009001
111111111111
m5.4xlarge
no
30
$347
Environment tag = dev
i-000000000000009010
111111111111
m5.4xlarge
no
30
$347
Environment tag = dev
i-00000000000000900d
111111111111
r5.2xlarge
no
30
$228
Environment tag = dev
i-000000000000009004
111111111111
m6i.xlarge
no
30
$87
Environment tag = dev
i-000000000000009013
111111111111
m6i.xlarge
no
30
$87
Environment tag = dev
4 EBS volumes and snapshots billed for the full period with no associated compute, $320/mo
$320
observed per month
$320
recoverable per month
4
resources
1/5
disruption to change
Assumption.A CUR does not carry EBS attachment state, so this is inferred from a volume billing every day of the period while nothing in the account consumed compute hours against it. Confirm with `aws ec2 describe-volumes --filters Name=status,Values=available` before deleting anything. Snapshots that are the only copy of a dataset are not waste regardless of what the billing says.
What to do.Snapshot then delete volumes confirmed as available. For snapshots, apply a lifecycle policy rather than deleting by hand.
$213k per month observed under these findings once each machine is counted once, all of it excluded from the recoverable total.
$22,326/mo on NVIDIA V100 (p3), superseded silicon
$22k
observed per month
$0
claimed as recoverable
4
resources
4/5
disruption to change
What is missing.Whether a newer family is cheaper for these workloads depends on model size, precision, memory footprint and batch size. None of that is in a Cost and Usage Report. Closing this gap needs one benchmark run of the real workload on a current-generation instance, measuring throughput per dollar rather than utilization. That is a day of work per distinct workload and it is the only thing that will settle it.
What to do.Benchmark the largest single workload on a current-generation instance before changing anything. Do not migrate a fleet on the strength of a spec sheet.
resource
account
instance type
accelerator
$ / month
i-00000000000000101b
111111111111
p3.8xlarge
NVIDIA V100
$8,930
i-00000000000000101d
111111111111
p3.8xlarge
NVIDIA V100
$8,930
i-00000000000000101a
111111111111
p3.2xlarge
NVIDIA V100
$2,233
i-00000000000000101c
111111111111
p3.2xlarge
NVIDIA V100
$2,233
$309,670/mo of GPU spend has no utilization telemetry (100% of GPU spend)
$310k
observed per month
$0
claimed as recoverable
40
resources
1/5
disruption to change
What is missing.No per-GPU utilization data exists for these instances, so no statement can be made about whether the silicon did work. Closing this gap means running the NVIDIA DCGM exporter with profiling metrics enabled and scraping DCGM_FI_PROF_SM_ACTIVE and DCGM_FI_PROF_PIPE_TENSOR_ACTIVE into Prometheus. Note that DCGM_FI_DEV_GPU_UTIL, the metric on most default dashboards, does not close this gap: it reports whether a kernel was resident, not how much of the chip it used. In our own lab measurement on one H100 rented on Lambda, published at nameplateanalytics.com/method, two configurations of one training job read 99.5% and 99.3% GPU utilization while one produced 26.6 times the real tokens per second of the other. That is one GPU and a configuration built for the test, so it shows what the reading misses, not how often. Export the result with its sample count and the span the samples cover; a mean on its own cannot be tied to any part of the billing period.
What to do.Deploy the NVIDIA DCGM exporter, add DCGM_FI_PROF_SM_ACTIVE to its counters file, which the shipped default comments out, and give the container SYS_ADMIN so the profiling fields can be read. Pod and namespace mapping comes from --kubernetes, which the published manifests already set; pod labels need --kubernetes-enable-pod-labels, which they do not. Two weeks of data is enough to size the next engagement.
resource
account
instance type
accelerator
$ / month
i-000000000000001001
111111111111
p5.48xlarge
NVIDIA H100
$40,157
i-000000000000001005
111111111111
p5.48xlarge
NVIDIA H100
$40,157
i-000000000000001025
111111111111
p5.48xlarge
NVIDIA H100
$28,913
i-000000000000001009
111111111111
p5.48xlarge
NVIDIA H100
$28,913
i-000000000000001021
111111111111
p5.48xlarge
NVIDIA H100
$24,897
i-000000000000001024
111111111111
p4d.24xlarge
NVIDIA A100
$16,020
i-000000000000001004
111111111111
p4d.24xlarge
NVIDIA A100
$16,020
i-000000000000001019
111111111111
p5.48xlarge
NVIDIA H100
$15,059
i-000000000000001000
111111111111
p4d.24xlarge
NVIDIA A100
$9,933
i-000000000000001008
111111111111
p4d.24xlarge
NVIDIA A100
$9,933
i-000000000000001020
111111111111
p4d.24xlarge
NVIDIA A100
$9,933
i-00000000000000101d
111111111111
p3.8xlarge
NVIDIA V100
$8,930
i-00000000000000101b
111111111111
p3.8xlarge
NVIDIA V100
$8,930
i-000000000000001018
111111111111
p4d.24xlarge
NVIDIA A100
$4,325
i-000000000000001023
111111111111
g5.12xlarge
NVIDIA A10G
$4,138
i-00000000000000101f
111111111111
g5.12xlarge
NVIDIA A10G
$4,138
i-000000000000001027
111111111111
g5.12xlarge
NVIDIA A10G
$4,138
i-000000000000001007
111111111111
g5.12xlarge
NVIDIA A10G
$4,138
i-000000000000001003
111111111111
g5.12xlarge
NVIDIA A10G
$2,980
i-000000000000001011
111111111111
g4dn.12xlarge
NVIDIA T4
$2,854
i-00000000000000100e
111111111111
g4dn.12xlarge
NVIDIA T4
$2,854
i-00000000000000100b
111111111111
g4dn.12xlarge
NVIDIA T4
$2,854
i-000000000000001014
222222222222
g4dn.12xlarge
NVIDIA T4
$2,854
i-00000000000000101c
111111111111
p3.2xlarge
NVIDIA V100
$2,233
i-00000000000000101a
111111111111
p3.2xlarge
NVIDIA V100
$2,233
Showing the 25 largest of 40 resources. The full list is in the machine-readable findings file that accompanies this report.
$97,207/mo of GPU capacity is claimed by a pod but has no utilization data
$97k
observed per month
$0
claimed as recoverable
9
resources
1/5
disruption to change
What is missing.A pod holding a GPU proves the accelerator is reserved, not that it is busy. Whether these GPUs are doing work needs DCGM_FI_PROF_SM_ACTIVE, and for tensor workloads DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, scraped per pod. Two things are usually in the way. DCGM_FI_PROF_SM_ACTIVE is commented out of the exporter's default counters file, so it has to be added and the exporter needs SYS_ADMIN to read it. And pod labels are only attached when the exporter runs with --kubernetes-enable-pod-labels, which the published Helm chart leaves off; pod and namespace mapping itself comes from --kubernetes, which the shipped manifests do set.
What to do.Add DCGM_FI_PROF_SM_ACTIVE to the exporter's counters file, give the container SYS_ADMIN, and turn on --kubernetes-enable-pod-labels so the metrics carry the pod they belong to. Scrape for two weeks, then re-run this audit. Nothing should be resized before that data exists.
4 Cluster allocation
How many of the accelerators you are paying for has anything asked for. This needs no new instrumentation: if a node advertises eight GPUs and no pod requests one, utilization is zero by definition.
Read from .status.capacity on each node and from the GPU requests of every non-terminated pod. 3 of 12 GPU nodes have no pod requesting an accelerator.
Illustrative figures from a synthetic specimen.
$60k
per month on GPUs nothing has requested
$97k
per month on GPUs a pod is holding
12
nodes matched to a line in the bill
Cost by namespace (illustrative figures from a synthetic specimen)
Each node's cost is split by the share of its GPUs a namespace requested. The unrequested share is not charged to anyone, which is the point of the figure above.
5 What this report cannot tell you
Each gap below is a question the billing data cannot answer, the dollars sitting behind it, and the specific measurement that would close it.
Question left open
Observed per month
What would close it
$309,670/mo of GPU spend has no utilization telemetry (100% of GPU spend)
$310k
No per-GPU utilization data exists for these instances, so no statement can be made about whether the silicon did work. Closing this gap means running the NVIDIA DCGM exporter with profiling metrics enabled and scraping DCGM_FI_PROF_SM_ACTIVE and DCGM_FI_PROF_PIPE_TENSOR_ACTIVE into Prometheus. Note that DCGM_FI_DEV_GPU_UTIL, the metric on most default dashboards, does not close this gap: it reports whether a kernel was resident, not how much of the chip it used. In our own lab measurement on one H100 rented on Lambda, published at nameplateanalytics.com/method, two configurations of one training job read 99.5% and 99.3% GPU utilization while one produced 26.6 times the real tokens per second of the other. That is one GPU and a configuration built for the test, so it shows what the reading misses, not how often. Export the result with its sample count and the span the samples cover; a mean on its own cannot be tied to any part of the billing period.
$97,207/mo of GPU capacity is claimed by a pod but has no utilization data
$97k
A pod holding a GPU proves the accelerator is reserved, not that it is busy. Whether these GPUs are doing work needs DCGM_FI_PROF_SM_ACTIVE, and for tensor workloads DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, scraped per pod. Two things are usually in the way. DCGM_FI_PROF_SM_ACTIVE is commented out of the exporter's default counters file, so it has to be added and the exporter needs SYS_ADMIN to read it. And pod labels are only attached when the exporter runs with --kubernetes-enable-pod-labels, which the published Helm chart leaves off; pod and namespace mapping itself comes from --kubernetes, which the shipped manifests do set.
$22,326/mo on NVIDIA V100 (p3), superseded silicon
$22k
Whether a newer family is cheaper for these workloads depends on model size, precision, memory footprint and batch size. None of that is in a Cost and Usage Report. Closing this gap needs one benchmark run of the real workload on a current-generation instance, measuring throughput per dollar rather than utilization. That is a day of work per distinct workload and it is the only thing that will settle it.
The rows above overlap: one machine can sit behind more than one open question, so the column does not add up and is not meant to. Counting each machine once, and setting aside what is already claimed elsewhere in this report, $213k per month is observed and not claimed. None of it is in the recoverable figure. Closing these gaps is the work of the next engagement, and the honest reason to do it is that the answer might be that nothing is wrong.
6 Order of work
Ordered by recoverable dollars per unit of disruption, not by dollars alone. The first item is the one that returns the most for the least argument.
Bar length is recoverable dollars per month. The disruption score at the right is the effort and risk of making the change, from 1 (delete an orphan) to 5 (re-architect a pipeline).
23 of 63 provisioned GPUs had no pod requesting them when the cluster was read, $60,432/mo
$60k per month, disruption 2 of 5. Scale the affected node groups down to the number of GPUs actually requested. Where a node group exists for burst capacity, set its floor to zero and let the cluster autoscaler bring it up on a pending pod.
14 production GPU instances run continuously at on-demand rates, $153,949/mo
$24k per month, disruption 3 of 5. Size a Compute Savings Plan to the observed floor of GPU usage, not to the peak. Commit to the level that has been running every day of the period and leave the rest on demand.
9 untagged instances read as non-production and run continuously, $11,916/mo
$8,369 per month, disruption 2 of 5. Confirm the classification, tag the resources so this stops being an inference, then schedule them off outside working hours.
10 tagged non-production instances run continuously, $6,495/mo, $4,706/mo of it GPU
$4,562 per month, disruption 2 of 5. Stop non-production instances outside working hours with an EventBridge schedule or an autoscaler floor of zero. GPU instances should be stopped rather than resized, because the accelerator is the entire cost.
Commitment purchased and not consumed: $1,216/mo of Reserved Instance capacity and $760/mo of Savings Plan commitment
$1,976 per month, disruption 2 of 5. Sell unused Standard RIs on the Reserved Instance Marketplace where the term allows, or move workloads onto the committed instance families so the commitment is consumed. Savings Plan commitments cannot be sold; the recovery is to shift eligible usage onto them before the term ends.
4 EBS volumes and snapshots billed for the full period with no associated compute, $320/mo
$320 per month, disruption 1 of 5. Snapshot then delete volumes confirmed as available. For snapshots, apply a lifecycle policy rather than deleting by hand.
7 Method
Costs are amortized. On-demand line items use unblended cost; reserved-instance-covered usage uses reservation_effective_cost; Savings-Plan-covered usage uses savings_plan_savings_plan_effective_cost; unused commitment is read from the RIFee and SavingsPlanRecurringFee rows. Savings Plan negation rows are excluded so that covered usage is not counted twice.
Commitment rows were read: 8,880 DiscountedUsage, 30 RIFee, 6,990 SavingsPlanCoveredUsage and 30 SavingsPlanRecurringFee rows. Unused commitment across them comes to $1,976 per month. The commitment finding above lists it. These dollars come from a synthetic fixture whose answer is known by construction.
Period figures are scaled to a 30.4-day month. Neither non-production finding is rated PROVEN, including the one that rests on your own Environment tag: the tag and the run hours are read from data you already own, but recovering the money means scheduling the machines off, and that assumes a working week. The assumed hours are printed on both findings. Where a resource is identified as non-production without a tag saying so, the signals used are printed next to it as well.
30 days of data; period figures scaled to a 30.4-day month by a factor of 1.013
1 parquet file(s), cur2 schema, duckdb backend
Cluster allocation data was supplied, so unrequested GPU capacity is read from the cluster rather than inferred from billing. Hours actually observed are rated PROVEN; the rest of the period is an extrapolation from those hours and is rated LIKELY with the assumption printed on the finding.