Why some costs stay hidden
Most teams know what their EC2 instances and databases cost. The surprises come from charges that sit underneath the architecture: traffic paths, addresses, logs and leftovers. They rarely show up as a single large line item. Instead they spread across services, often under the “EC2-Other” or “VPC” headings in AWS Cost Explorer, and grow with traffic rather than with the number of servers.
The fastest way to find them is to open Cost Explorer, group by Usage type, and sort by cost. The sections below cover the usage types that most often deserve a second look.
NAT gateway data processing
A NAT gateway has two charges: an hourly charge for each gateway, and a data processing charge for every gigabyte that passes through it. The processing charge applies on top of any data transfer charges.
That matters when private subnets send heavy traffic through NAT to AWS services. A common example is an application in a private subnet that reads and writes large volumes to Amazon S3, or a cluster that pulls container images through NAT.
How to reduce it:
- Add gateway VPC endpoints for Amazon S3 and Amazon DynamoDB. There is no additional charge for gateway endpoints, and traffic to those services stops going through the NAT gateway.
- For other high-volume AWS services, compare the cost of interface VPC endpoints (AWS PrivateLink) with the NAT processing they would replace.
- Keep NAT gateways in the same Availability Zone as the subnets that use them, so you do not add cross-AZ charges on top.
Data transfer between Availability Zones
Traffic between resources in the same Availability Zone over private IP addresses is generally free. Traffic between Availability Zones in the same Region is charged per gigabyte in each direction. Multi-AZ designs are the right choice for resilience, but chatty services that call each other across zones, replicas that sync constantly, and Kubernetes pods scheduled without regard to zone can add up.
How to reduce it:
- Look for the
DataTransfer-Regional-Bytesusage type in Cost Explorer to see how much you spend on cross-AZ traffic. - Use topology-aware routing in Kubernetes and keep tightly coupled services in the same zone where resilience requirements allow.
- Check whether load balancer cross-zone settings match your design.
Data transfer out to the internet
Data sent from AWS to the internet is charged per gigabyte after a free allowance of 100 GB per month aggregated across services and Regions. Large downloads, media, backups sent off AWS and APIs with heavy responses drive this cost.
How to reduce it: serve static and cacheable content through Amazon CloudFront, compress responses, and check that backups and replication are not leaving AWS when they do not need to.
Public IPv4 addresses
Since February 1, 2024, AWS charges for every public IPv4 address, whether it is attached to a resource or idle. The rate on the Amazon VPC pricing page is $0.005 per IP per hour for both in-use and idle addresses. This includes Elastic IP addresses, auto-assigned public IPs on EC2 instances, and the public addresses used by internet-facing load balancers and NAT gateways.
How to reduce it:
- Use Public IP Insights in Amazon VPC IP Address Manager (IPAM), a no-cost feature, to list public IPv4 addresses across your accounts.
- Release Elastic IP addresses that are not attached to anything.
- Put instances in private subnets behind a load balancer instead of giving each one a public IP, and turn off auto-assign public IP on subnets that do not need it.
- Where clients support it, use IPv6.
CloudWatch Logs ingestion and retention
Amazon CloudWatch Logs charges for data ingested and for data stored. Verbose application logs, debug logging left on in production, VPC Flow Logs and load balancer access logs can generate large volumes.
Two defaults make this worse. New log groups keep data indefinitely unless you set a retention period, and nobody revisits the log level once a service is stable.
How to reduce it:
- Set a retention period on every log group, and enforce it with infrastructure as code.
- Lower log levels in production and drop noisy, low-value messages at the source.
- For logs you keep for audit or occasional investigation, consider the Essentials log class (formerly Infrequent Access), which has a lower ingestion price per GB but fewer features. A log group’s class cannot be changed after it is created.
- Send high-volume logs that are rarely queried directly to Amazon S3 where the service supports it.
Idle EBS volumes and old snapshots
When an EC2 instance is terminated, attached EBS volumes are not always deleted; it depends on the volume’s delete-on-termination setting. Unattached volumes keep billing every month. Stopped instances also keep paying for their volumes.
Snapshots are incremental, but they accumulate. A daily snapshot schedule with no expiry, or snapshots of volumes that no longer exist, can cost more than the volumes themselves.
How to reduce it:
- Filter the EC2 console or use AWS Trusted Advisor and AWS Compute Optimizer to find unattached and underused volumes.
- Use Amazon Data Lifecycle Manager or AWS Backup to set snapshot retention.
- Move snapshots you must keep for 90 days or more, but rarely restore, to EBS Snapshots Archive.
- Migrate gp2 volumes to gp3, which has a lower price per GiB.
Oversized and outdated RDS databases
Databases are often sized for a launch peak and never revisited. Compute Optimizer gives rightsizing recommendations for Amazon RDS and Aurora, and Amazon CloudWatch and Performance Insights show whether CPU, memory and I/O justify the current instance class. Check provisioned IOPS and storage as well as the instance.
There is a second, newer hidden cost: Amazon RDS Extended Support. If a database runs a major engine version past its RDS end of standard support date and is enrolled in Extended Support, AWS continues to run it and charges an additional fee. Keep an inventory of engine versions and plan major version upgrades before standard support ends.
Make hidden costs visible
The pattern behind all of these is the same: costs that scale with traffic or time rather than with resources you deliberately created. A few habits keep them in view:
- Review Cost Explorer by usage type every month, not just by service.
- Set AWS Budgets alerts per account and turn on AWS Cost Anomaly Detection.
- Tag resources with an owner so every unexpected line item has someone to ask.
9Acts is an AWS Advanced Tier Services Partner and AWS MSP Partner and has helped clients run AWS since 2016. If you want a second pair of eyes on your bill, see our cloud optimization service.
