DevOps

AWS cost optimization: complete FinOps guide for technical teams

Published Apr 12, 2026Updated Apr 12, 2026By Valendra

AWS cost optimization guide with FinOps: right-sizing, Reserved Instances, Savings Plans, Spot, Kubernetes cost control, and a continuous review process.

AWS cost optimization: complete FinOps guide for technical teams

AWS cost optimization is the problem every CTO discovers late. Not because it is hard to understand, but because the bill grows in ways that do not trigger alarms until it is already a real budget problem. EC2 instances provisioned for a traffic spike that was never adjusted. RDS databases with twice the storage they actually use. EKS node groups sized for the worst-case scenario from eighteen months ago. NAT Gateways processing traffic that could go direct. The common pattern is that each individual decision was reasonable at the time. The accumulation is what gets expensive.

This guide is not a list of configuration tricks. It is a decision framework for technical teams that want to reduce their AWS bill sustainably, without introducing operational risk or creating new technical debt. The objective is to spend less on what does not differentiate, to invest more in what does.

Where cost accumulates in AWS

Before optimizing, you need to know where the money is. Cost Explorer with per-service, per-account, and per-tag granularity is the mandatory starting point. Without that visibility, optimization is guesswork.

EC2 and compute instances are typically the largest category in most organizations. Cost accumulates through three paths: oversized instances that never reached the peak they were provisioned for, stopped instances that continue to generate attached EBS cost, and capacity reservations that were sized poorly and have not been reviewed in more than twelve months. On-demand without reservations on predictable workloads is consistently the most expensive way to run compute on AWS.

RDS and managed databases accumulate cost through instance overprovisioning, storage with autoscaling enabled but no upper limit, and automated snapshots retained for longer than necessary. Multi-AZ in development and staging environments is a common source of unjustified spend.

Data transfer is the category that generates the most surprises because it does not appear visibly in initial budgets. Egress from AWS to the internet, cross-region transfer, and traffic between availability zones within the same region are priced differently and accumulate quickly in architectures that do not design for them explicitly. A service making cross-AZ calls unnecessarily can double its networking cost without any dashboard making it obvious.

EKS and node groups are where the most cost is lost in organizations that have adopted Kubernetes. A node group sized to tolerate the loss of a node in the worst-case traffic scenario from last year can permanently run at 40 to 50 percent unused capacity. The fragmentation of workloads across multiple node groups with poor bin-packing multiplies that problem.

Idle and forgotten resources: unassociated Elastic IPs, orphaned EBS volumes, load balancers with no traffic, snapshots from years ago, Lambda functions with inherited memory configurations. Individually they are small. In large AWS accounts, the sum can be significant and represents pure waste.

Oversized or poorly converted reservations are the hidden cost in organizations that already made a first optimization effort. A three-year Reserved Instance for an instance type that was later migrated, or an overly aggressive Savings Plan that no longer reflects actual usage, can become a spend commitment with no real utilization.

Right-sizing: the most direct lever

Right-sizing is the optimization with the fastest ROI and lowest risk when done with data. The reason many teams do not do it systematically is that it requires analysis time, a controlled change process, and willingness to touch infrastructure that "works." Those three factors are exactly what a FinOps culture addresses.

AWS Compute Optimizer is the correct starting point. It analyzes CloudWatch metrics from the last two weeks and generates instance recommendations for EC2, Auto Scaling groups, Lambda functions, and EBS volumes. What Compute Optimizer does not do is consider operational context: whether an instance needs headroom for SLA reasons, whether the usage pattern has seasonality that does not appear in the analyzed period, or whether there are instance type constraints due to licensing or hardware dependencies. That judgment remains with the team.

The practical right-sizing process has three steps. First, identify instances with CPU or memory utilization consistently below 20 percent during normal load periods. Second, rank by annual cost to prioritize the highest-impact ones. Third, define the reduction policy: how much headroom is acceptable per workload type, how many availability zones you need, and what the validation process is before applying the change in production.

Graviton migration deserves its own paragraph because it combines right-sizing with an architecture change that has significant cost impact. Graviton 3 and Graviton 4-based instances offer a 20 to 40 percent performance-per-price improvement over equivalent x86 instances for most web server, API, and data processing workloads. The constraint is compatibility: if software has native compilation dependencies for x86, migration requires recompilation and validation. For workloads running in containers on modern architectures, that barrier is typically low.

A practical rule: start right-sizing in staging and development environments, where operational risk is lower, to calibrate the process before applying it in production. The savings in staging are marginal, but the process validated there reduces risk when it is applied where it actually matters.

Reserved Instances and Savings Plans

The capacity purchasing model in AWS has more options than most teams actively manage, and that lack of active management is where thousands of dollars per month are lost in mid-size organizations.

Reserved Instances provide a discount in exchange for a commitment to use a specific instance type in a region for one or three years. They are the right choice when the workload is stable, predictable, and tied to a specific instance type that is not going to change. Convertible RIs allow changing family, type, operating system, and tenancy within the commitment period, at the cost of a slightly lower discount. Standard RIs have a higher discount but cannot be modified. The decision between convertible and standard depends on how confident you are about your infrastructure architecture within the commitment horizon.

Savings Plans are more flexible than RIs and have become the preferred option for most teams. Compute Savings Plans apply automatically to any EC2, Fargate, or Lambda usage across any region, instance family, and operating system, in exchange for an hourly spend commitment. EC2 Instance Savings Plans are less flexible but offer a greater discount. The advantage of Savings Plans is that instance optimization and migration between types does not "break" the commitment, making them far more compatible with a culture of continuous right-sizing.

Spot Instances are the highest-discount option, typically 60 to 90 percent off the on-demand price, but with the condition that AWS can reclaim the instance with two minutes of warning. They are appropriate for interruption-tolerant workloads: batch processing, model training, CI/CD tasks, and ETL jobs that can be interrupted and restarted. They are not appropriate for stateful databases, APIs with strict latency SLAs, or any workload that cannot handle a sudden termination cleanly.

The optimal combination for most organizations is: Savings Plans for the predictable compute baseline, Spot for variable and interruption-tolerant loads, and on-demand only for unpredictable overflow and workloads that genuinely cannot tolerate interruption or commit to an instance type. The typical mistake is keeping everything on-demand because "something is always changing." In organizations with more than three years of AWS history, that pure on-demand posture usually represents 20 to 35 percent of unoptimized compute spend.

Kubernetes and EKS: where the most cost is lost

Kubernetes is extraordinarily good at consolidating compute, but it requires active configuration for that consolidation to happen. By default, EKS makes scheduling decisions that are correct for availability, not for cost. The difference between a default configuration and a cost-optimized configuration can be 30 to 50 percent of compute spend for organizations with mid-size clusters.

Node group overprovisioning is the most common problem. A node group with large instances and a high minimum node count guarantees availability, but if pods do not fill that capacity, you pay for compute that does nothing. The first step is measuring actual CPU and memory utilization at the cluster, namespace, and workload level. CloudWatch Container Insights or Prometheus with Grafana provide that visibility. Without it, any sizing decision is guesswork.

Karpenter is AWS's answer to poor bin-packing by the Cluster Autoscaler. Instead of scaling predefined node groups, Karpenter provisions nodes of any type according to the exact requirements of pending pods. This allows using Spot instances more aggressively, matching node size to actual workload, and consolidating pods onto fewer nodes when load drops. The articles EKS Auto Mode vs Karpenter and Kubernetes in production in 2026 cover the architecture decision in detail.

Cost attribution per namespace is the most ignored FinOps pillar in Kubernetes. If you do not know what each team spends inside the cluster, you cannot hold them accountable for reducing it. Attribution requires consistent tagging of pods and namespaces, and a tool that correlates that tagging with actual node spend. OpenCost and Kubecost are the most widely adopted open-source options for this use case.

Poorly calibrated resource requests and limits are the origin of the previous problem. If pods declare CPU and memory requests that do not reflect their actual usage, the scheduler makes bin-packing decisions based on incorrect data and the node appears full when it actually has available capacity. Auditing requests versus actual usage with Vertical Pod Autoscaler in recommendation mode is the fastest way to identify overdeclared pods.

Monthly cost review process

Cost optimization without process degrades. One-off decisions that generate savings are undone with the next wave of work if there is no review cycle to maintain them. The FinOps model proposes four phases that repeat monthly.

Discover: in the first week of the month, review Cost Explorer by service and tag, compare with the previous month, and identify the ten highest-spend items. Confirm that all resources have a team and environment tag. Untagged resources are immediate candidates for review or deletion.

Optimize: in the second week, execute the identified actions. Right-sizing of instances identified last month, review of reservations expiring in the next ninety days, deletion of confirmed idle resources, and review of budget alerts. This phase requires coordination with the teams that own each workload. It cannot be done unilaterally.

Operate: for the rest of the month, keep controls running. Active budget alerts per account and service, updated cluster utilization dashboard, and a clear process for teams to request additional capacity with justification.

Measure: at the end of the month, compare the result against the savings target, document what worked and what did not, and adjust hypotheses for the next cycle. Without measurement, the process loses internal credibility and gets abandoned.

Common mistakes that inflate the bill

Knowing the most common mistakes allows you to prioritize them in the initial audit. In organizations with more than two years of AWS history, several of these appear simultaneously.

Orphaned EBS volumes and snapshots without a retention policy are the classic invisible spend. When an EC2 instance is terminated, the EBS volume may remain. At one dollar per GB per month for gp3 storage, one hundred volumes of fifty GB each is five thousand dollars per month of pure waste. Snapshots without an expiration policy accumulate for years and are rarely audited.

Resources without an owner tag: if a resource has no tag identifying the responsible team or project, no one examines it in the monthly review and no one has an incentive to delete it. Tagging must be a non-negotiable requirement in the deployment process, not a cleanup effort after the fact.

Unnecessary cross-AZ data transfer: many internal services make cross-availability-zone calls without needing multi-AZ availability. If a service and its database are in different zones by default, every query pays cross-AZ network traffic. Availability zone decisions have to be part of architecture design, not the default result of the console wizard.

NAT Gateway for traffic that could use private endpoints: if EKS pods access S3 or DynamoDB through the NAT Gateway, they are paying for traffic that could go through a VPC endpoint with no transfer cost. S3 and DynamoDB endpoints are free. This appears frequently in audits of mature AWS accounts.

Poorly managed purchase commitments: a Reserved Instance purchased two years ago for an instance type that was later migrated to Graviton, or a Savings Plan whose commitment level exceeds current actual usage. These situations accumulate without anyone reviewing them because the spend is already committed and appears "paid for." RI and SP utilization audits must be part of the monthly process.

Impact table by category

CategoryTypical savingsEffortOperational risk
EC2 right-sizing20-40% of EC2 spendMediumLow with prior validation
Graviton migration20-30% of affected EC2 spendMedium-highMedium, requires testing
Reserved Instances / Savings Plans30-60% vs on-demandLowLow, only commitment risk
Spot for tolerant workloads60-80% vs on-demandMediumHigh if workload is not tolerant
Karpenter on EKS20-40% of node spendHighMedium, requires scheduling validation
Idle resource deletionVariable (typically 5-15%)LowVery low if inactivity confirmed
VPC endpoints for S3/DynamoDB30-80% of NAT Gateway spendLowVery low
Snapshot retention policyVariableLowVery low with grace period
Kubernetes cost attributionVisibility, not direct savingsMediumNo operational risk
Purchase commitment review10-25% of underutilized reservationsLowNo operational risk

When to act

If the AWS bill grows faster than actual usage, or if you cannot answer "which team generates this cost" for the main items on the bill, the FinOps process is not working. The first step is visibility: consistent tagging, Cost Explorer by team, and a monthly review process.

If you need technical support to reduce spend sustainably without introducing operational risk, Valendra's cloud and DevOps consulting: AWS, Kubernetes, Terraform team works from the initial audit through the implementation of continuous controls.

Newsletter

Get the next technical briefing before the problem gets expensive

A short selection on cloud, data, AI, and software for teams operating production systems.

Low frequency. High signal.

By subscribing, you agree to receive Valendra's technical newsletter. You can unsubscribe at any time.

More technical articles