Previous-generation instances run on hardware the provider no longer builds out, at a price that rarely undercuts the newer generation: an m4.large costs more than an m7i.large of the same size, a D4 v3 about the same as a D4 v5, an n1-standard-4 about the same as an n2-standard-4, with less performance per hour. The saving comes from both halves, the lower or equal price and the higher performance that lets a smaller size do the job. The fix belongs to the team that maintains the image and the deployment template, because a generation change starts there, not in the console.
Symptom
The bill names the generation on every line. On AWS it sits in the lineItem/UsageType, such as EUC1-BoxUsage:m4.large, and in product/instanceType; on Azure MeterSubCategory names the series, such as Dv3/DSv3 Series, and MeterName the size; on Google Cloud the SKU reads N1 Predefined Instance Core running in Frankfurt instead of N2 Instance Core running. An estate in which these lines carry a visible share of instance hours pays for performance it would get cheaper on the current generation. The list prices per generation and European region are on the instance comparison; the families and their naming rules are in virtual machines and instance families.
How to detect it
AWS
AWS lists its previous generations with their recommended successors on a page of their own (read on 2026-10-21): T1 to T3, T3a or T4g, M1 and M3 to M7i, M7g or M7a, I2 to I3, M2, CR1 and R3 to R4, HS1 to D2, G2 to G3, A1 to C7g; M4, C3, C4 and R4 are in the table without a stated successor, and the naming rule leads them to M7, C7 and R7. Which types AWS counts as current, the API says itself:
aws ec2 describe-instance-types --filters Name=current-generation,Values=false \
--query 'InstanceTypes[].InstanceType' --output text | tr '\t' '\n' | sort
Your own estate by type, with counts:
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].InstanceType' --output text | tr '\t' '\n' | sort | uniq -c | sort -rn
Compute Optimizer sometimes recommends a new generation type even for instances it rates "Optimized" and shows the price difference per option:
aws compute-optimizer get-ec2-instance-recommendations \
--query 'instanceRecommendations[].[instanceArn,currentInstanceType,finding,recommendationOptions[0].instanceType,recommendationOptions[0].savingsOpportunity.estimatedMonthlySavings.value]' \
--output table
In billing data the previous-generation share is the sum of BoxUsage hours whose product/instanceType is on the describe-instance-types list against all BoxUsage hours (AWS Cost and Usage Report).
Azure
Microsoft keeps its previous-generation series in a list of their own and has announced the retirement of Dv3, Dsv3, Ev3 and Esv3 for 2029-11-15; reservations for these series can no longer be bought or renewed after 2026-07-01, and the recommended targets are Dv5, Dsv5, Ddv5, Ddsv5, Dasv5 and Dadsv5, or the E-series in v5 (modernization guide). The estate by size:
az vm list --query "[].hardwareProfile.vmSize" -o tsv | sort | uniq -c | sort -rn
The sizes ending in _v2 or _v3 or carrying no version number are the candidates. Azure Advisor explicitly includes sizes of a newer version in its resize recommendation, D3v2 to D2v3 for instance, when the load fits there more cheaply:
az advisor recommendation list --category Cost --query "[?contains(shortDescription.problem, 'virtual machine')].{resource:resourceMetadata.resourceId, problem:shortDescription.problem}" -o table
In the cost export the series is readable from MeterSubCategory; the sum of Quantity per series against the total is the share (Azure cost exports).
Google Cloud
Google places N1 and its shared-core types as the first generation of the general-purpose family and E2, N2, N2D, T2A and T2D as the second (general-purpose machine family). The estate by series:
gcloud compute instances list --format="value(machineType.basename())" | cut -d- -f1 | sort | uniq -c | sort -rn
The machine type recommender reads eight days of CPU and memory usage and recommends a predefined or custom type available in the zone (machine type recommendations):
gcloud recommender recommendations list --project=<project-id> --location=<zone> \
--recommender=google.compute.instance.MachineTypeRecommender --format="table(name.basename(),description,primaryImpact.category)"
In the billing export the generation is part of the sku.description; the sum of usage.amount on N1 SKUs against all Instance Core running SKUs is the share (Google Cloud billing export).
How to fix it
- Pick the target size from the provider's successor table and check it against the recommender: one size smaller is often enough, because the new generation does more per vCPU.
- Check the prerequisites a generation change brings: on AWS the ENA network driver and the NVMe driver for Nitro types and an HVM image instead of PV; on Azure accelerated networking, which the Intel v5 series require, and a supported image; on Google Cloud nothing comparable, but a look at local SSDs and GPUs, which not every series offers.
- Change the type, on all three while stopped. AWS:
aws ec2 modify-instance-attribute --instance-id i-0123456789abcdef0 --instance-type '{"Value":"m7i.large"}' --dry-run, then without--dry-run. Azure:az vm resize --resource-group <rg> --name <vm> --size Standard_D2s_v5, which deallocates the VM when the size is not available on its host. Google Cloud:gcloud compute instances set-machine-type <vm> --zone=<zone> --machine-type=n2-standard-2aftergcloud compute instances stop. - Change the template: launch templates, scale set models, instance templates and the infrastructure definitions new instances come from, or the old generation returns with the next deployment.
The new hourly rate applies from the start; the following month's invoice shows the full effect.
Risks and side effects
- A commitment on the old family stays. A Standard Reserved Instance is tied to its family, a Convertible one can be exchanged, a Compute Savings Plan covers any family; an Azure reservation applies to its size group and can be exchanged or traded into a savings plan under Microsoft's rules; a resource-based committed use discount on Google Cloud applies per machine family and region, a spend-based one does not (commitment exchange, cancellation and expiry).
- A change of architecture is a step of its own with a page of its own, moving to ARM instances; M7g instead of M7i is a port, not a resize.
- Licences per core, for databases for instance, move with the vCPU count of the target size in both directions.
- Local instance store is lost on a move to a type without it; data on it has to go to a volume first.
- Performance is measurable only after the change: one size smaller saves only if response times hold. A week's comparison with the metrics of rightsizing is part of the step.
How to verify the saving
Before: the hours and the amount of the BoxUsage, Virtual Machines and Instance Core running lines per resource in the last full month, with lineItem/UnblendedRate or EffectivePrice as the hourly rate. After: the same resource in the first full month on the new type, with equal or fewer hours and the new rate; the difference is the saving, and the previous-generation share of all instance hours is the figure for the estate. The recommender's price difference is the estimate, the team's consent makes it accepted, the change implemented, and the following month's invoice realises it in the pattern of estimated, accepted, implemented, verified. Where a commitment keeps covering the old family, only its utilisation shows whether the saving is real.
Sources
Read on 2026-10-21. Previous generation instances on AWS, describe-instance-types, Compute Optimizer EC2 recommendations, Azure previous generation sizes, Azure retired VM sizes modernization guide, Azure, modernize to the v5 series, Azure Advisor, underutilized virtual machines, General-purpose machine family on Google Cloud, Machine type recommendations.