IPv6 Cost Hacks for AWS VPC: How to Cut VPC Networking Bills Dramatically
A cloud team is facing rising VPC networking spend and needs practical IPv6-first patterns to reduce public IPv4 and NAT-driven cost without disrupting production traffic.
IPv6 Cost Hacks for AWS VPC: How to Cut VPC Networking Bills Dramatically
Scenario
A cloud team is facing rising VPC networking spend and needs practical IPv6-first patterns to reduce public IPv4 and NAT-driven cost without disrupting production traffic.
Scope
This guide covers IPv6 cost levers across AWS VPC design, including public IPv4 reduction, egress-only internet gateway routing, NAT64 boundaries, ALB and CloudFront edge patterns, and migration phases.
How to use this guide
Use this article as a migration runbook: baseline your current IPv4 and NAT spend, implement low-risk IPv6 changes first, then progressively move to IPv6-first with minimal compatibility bridges.
AWS VPC itself is rarely the expensive part. The real bill usually comes from public IPv4 addresses, NAT Gateways, NAT data processing, cross-AZ routing, and sometimes unnecessary endpoints. IPv6 helps because it lets you remove or reduce several IPv4-dependent components at the same time.
The biggest lever: AWS charges for every public IPv4 address, whether it is attached or idle, at $0.005/hour, which is about $3.60/month per public IPv4 on a 30-day month. NAT Gateway also adds hourly and per-GB processing charges; AWS’s pricing example uses $0.045/hour and $0.045/GB in US East Ohio.
The core idea
Most classic VPC designs look like this:
Internet
|
Public IPv4 ALB
|
Private subnets
|
NAT Gateway with Elastic IPv4
|
Internet / AWS APIs / package repos
The optimized IPv6-first version looks more like this:
Internet users
|
CloudFront or IPv6-capable ALB
|
Dual-stack / IPv6 workloads
|
Egress-only Internet Gateway for IPv6
|
NAT64 only for legacy IPv4 destinations
This does not mean “delete IPv4 everywhere tomorrow.†The best strategy is IPv6-first, IPv4-minimal.
Why IPv6 lowers VPC cost
1. Remove public IPv4 from workloads
Do not give EC2, ECS tasks, RDS, bastions, or random ENIs public IPv4 unless they truly need it. Every public IPv4 address now has a recurring hourly cost. That includes idle Elastic IPs and in-use public IPv4 addresses attached to AWS resources.
Bad pattern:
EC2 instance 1 -> public IPv4
EC2 instance 2 -> public IPv4
EC2 instance 3 -> public IPv4
ALB -> 2 public IPv4 addresses
NAT Gateway -> 1 Elastic IPv4
Better pattern:
EC2/ECS/RDS -> private IPv4 + IPv6
ALB/CloudFront -> only public entry point
NAT Gateway -> temporary compatibility layer only
Even a small environment can easily waste:
| Resource | Public IPv4 count | Approx monthly IPv4 cost |
|---|---|---|
| 3 public EC2 instances | 3 | $10.80 |
| 1 public ALB, usually 2 AZs | 2 | $7.20 |
| 1 NAT Gateway Elastic IP | 1 | $3.60 |
| 4 forgotten idle EIPs | 4 | $14.40 |
| Total | 10 | $36/month only for IPv4 addresses |
That is before NAT hourly charges, data transfer, ALB, EC2, ECS, RDS, CloudWatch, or Route 53.
2. Replace NAT Gateway for IPv6 egress
For IPv4-only private subnets, outbound internet usually needs a NAT Gateway. For IPv6, AWS gives you a better primitive: Egress-only Internet Gateway.
An egress-only Internet Gateway allows outbound IPv6 traffic from VPC resources while blocking internet-initiated inbound IPv6 connections. AWS states there is no charge for the egress-only Internet Gateway itself; standard data transfer charges still apply.
Classic private subnet route:
0.0.0.0/0 -> NAT Gateway
IPv6-first private subnet route:
::/0 -> Egress-only Internet Gateway
This is one of the strongest cost hacks because NAT Gateway has two cost dimensions: hourly cost and per-GB processing cost. In AWS’s pricing example, NAT Gateway costs $0.045/hour plus $0.045/GB processed.
3. Use NAT64 only as a bridge, not as the default path
IPv6-only workloads cannot talk directly to IPv4-only services. AWS solves this with DNS64 + NAT64, where Route 53 Resolver synthesizes IPv6 records and the NAT Gateway translates IPv6-to-IPv4.
Important: NAT64 still uses NAT Gateway, so it is not “free IPv4 escape.†It is a compatibility bridge.
Recommended routing model:
IPv6 destination:
::/0 -> Egress-only Internet Gateway
IPv4-only destination from IPv6 workload:
64:ff9b::/96 -> NAT Gateway
AWS services:
Prefer IPv6-capable private endpoints or gateway endpoints
AWS’s NAT64 documentation shows exactly this split: route 64:ff9b::/96 to NAT Gateway and route ::/0 to an egress-only Internet Gateway or Internet Gateway.
The trick is to make NAT64 the exception path, not the default path.
4. Use dualstack-without-public-ipv4 for ALB when possible
Application Load Balancer supports an IP address type called:
dualstack-without-public-ipv4
This gives the ALB public IPv6 addresses plus private IPv4/IPv6 addresses, without public IPv4 on the load balancer. AWS documents this option for ALB.
Command:
aws elbv2 set-ip-address-type `
--load-balancer-arn "arn:aws:elasticloadbalancing:REGION:ACCOUNT:loadbalancer/app/NAME/ID" `
--ip-address-type dualstack-without-public-ipv4 `
--region us-east-1
Caveat: AWS notes that ALB authentication with an Identity Provider or Amazon Cognito requires IPv4 connectivity from the ALB; without public IPv4, that authentication flow can fail with HTTP 500.
Use this mode for:
| Workload | Good fit? | Notes |
|---|---|---|
| Internal tools used by IPv6-capable networks | Yes | Excellent cost reduction |
| API consumed by modern cloud clients | Yes | Test clients first |
| Public website with unknown users | Maybe | Some users still lack IPv6 |
| ALB using Cognito/OIDC auth | Risky | AWS documents IPv4 dependency |
| Behind CloudFront | Strong option | CloudFront can serve IPv4 and IPv6 viewers |
5. Put CloudFront at the edge
CloudFront supports both IPv4 and IPv6 from clients to AWS edge locations, and it also supports IPv6 or dual-stack connectivity toward origins.
This opens a powerful architecture:
IPv4 + IPv6 users
|
CloudFront
|
IPv6 / dual-stack origin
|
ALB without public IPv4
|
Private workloads
This is especially attractive for public websites because you can continue serving IPv4 users at the edge while reducing IPv4 exposure deeper inside your VPC. AWS announced IPv6 origin support for CloudFront in September 2025, including IPv6-only and dual-stack custom origins, excluding S3 and VPC origins.
For a web app like a quiz/exam platform, the best pattern is usually:
Users
-> CloudFront + WAF
-> IPv6/dual-stack ALB
-> ECS/Fargate private services
-> RDS private only
6. Stop sending AWS service traffic through NAT
A very common waste pattern:
Private ECS task -> NAT Gateway -> S3/ECR/CloudWatch/STS/Secrets Manager
This creates NAT processing charges for traffic that should stay inside AWS networking.
Use:
| Destination | Better option |
|---|---|
| S3 | Gateway VPC Endpoint |
| DynamoDB | Gateway VPC Endpoint |
| CloudWatch Logs | Interface VPC Endpoint |
| ECR API | Interface VPC Endpoint |
| ECR Docker registry | Interface VPC Endpoint |
| Secrets Manager | Interface VPC Endpoint |
| SSM | Interface VPC Endpoint |
| STS | Interface VPC Endpoint where useful |
AWS’s VPC pricing page explicitly says that an S3 Gateway VPC Endpoint can avoid NAT Gateway data-processing charges, and that gateway endpoints have no hourly charge and no data processing charge.
For interface endpoints, choose IPv6 or dual-stack when the AWS service supports it. AWS documents that interface endpoints can be IPv4, IPv6, or dual-stack depending on subnet compatibility and service support.
7. The “exponential†saving effect
The saving becomes large because each change removes multiple cost layers.
Example baseline:
| Item | Monthly estimate |
|---|---|
| 2 NAT Gateways across 2 AZs | $64.80 |
| 200 GB NAT processing | $9.00 |
| 6 public IPv4 addresses | $21.60 |
| Forgotten 4 idle EIPs | $14.40 |
| Total avoidable networking waste | $109.80/month |
Optimized IPv6-first version:
| Item | Monthly estimate |
|---|---|
| Egress-only Internet Gateway | $0 component cost |
| S3 Gateway Endpoint | $0 hourly / processing |
| Public IPv4 removed from instances | $0 |
| Idle EIPs released | $0 |
| One temporary NAT64 bridge | $32.40 + reduced GB |
| Likely optimized waste | ~$32.40/month + smaller NAT traffic |
The result is not mathematically exponential, but operationally it feels exponential because you are cutting IPv4 address cost, NAT hourly cost, and NAT per-GB cost together.
Recommended target architecture
+----------------+
Users IPv4/IPv6 -------->| CloudFront |
+-------+--------+
|
v
+---------------------------+
| ALB dualstack / no pub v4 |
+-------------+-------------+
|
+-----------------+-----------------+
| |
+-------v-------+ +-------v-------+
| ECS/Fargate | | ECS/Fargate |
| private subnet| | private subnet|
| IPv6 enabled | | IPv6 enabled |
+-------+-------+ +-------+-------+
| |
+-----------------+-----------------+
|
+-------------------------+--------------------------+
| |
v v
Egress-only IGW for IPv6 VPC Endpoints for AWS APIs
|
v
IPv6 Internet
Legacy IPv4 only:
IPv6 workload -> 64:ff9b::/96 -> NAT64/NAT Gateway -> IPv4 Internet
Practical migration checklist
Phase 1 — Measure before changing
Use this to find Elastic IPs:
aws ec2 describe-addresses `
--region us-east-1 `
--query "Addresses[].{PublicIp:PublicIp,AllocationId:AllocationId,AssociationId:AssociationId,InstanceId:InstanceId,NetworkInterfaceId:NetworkInterfaceId}" `
--output table
Find ENIs with public IPv4:
aws ec2 describe-network-interfaces `
--region us-east-1 `
--filters Name=association.public-ip,Values=* `
--query "NetworkInterfaces[].{ENI:NetworkInterfaceId,PublicIp:Association.PublicIp,PrivateIp:PrivateIpAddress,Description:Description,Status:Status}" `
--output table
Find NAT Gateways:
aws ec2 describe-nat-gateways `
--region us-east-1 `
--query "NatGateways[].{NatGatewayId:NatGatewayId,State:State,SubnetId:SubnetId,VpcId:VpcId,PublicIp:NatGatewayAddresses[0].PublicIp}" `
--output table
Phase 2 — Add IPv6 to the VPC and subnets
Target model:
VPC: IPv4 CIDR + IPv6 CIDR
Public subnets: IPv4 + IPv6
Private subnets: IPv4 + IPv6, or IPv6-only for selected workloads
AWS tracks which services support dual-stack, IPv6-only, public IPv6 endpoints, and private IPv6 endpoints in its VPC IPv6 support matrix.
Phase 3 — Add egress-only IPv6
Create egress-only Internet Gateway:
aws ec2 create-egress-only-internet-gateway `
--vpc-id vpc-xxxxxxxx `
--region us-east-1
Add private subnet IPv6 default route:
aws ec2 create-route `
--route-table-id rtb-xxxxxxxx `
--destination-ipv6-cidr-block "::/0" `
--egress-only-internet-gateway-id eigw-xxxxxxxx `
--region us-east-1
Phase 4 — Keep NAT only for IPv4-only dependencies
For IPv6-only workloads that still need IPv4-only destinations:
aws ec2 create-route `
--route-table-id rtb-xxxxxxxx `
--destination-ipv6-cidr-block "64:ff9b::/96" `
--nat-gateway-id nat-xxxxxxxx `
--region us-east-1
Enable DNS64:
aws ec2 modify-subnet-attribute `
--subnet-id subnet-xxxxxxxx `
--enable-dns64 `
--region us-east-1
Phase 5 — Move ALB away from public IPv4
For compatible workloads:
aws elbv2 set-ip-address-type `
--load-balancer-arn "ALB_ARN_HERE" `
--ip-address-type dualstack-without-public-ipv4 `
--region us-east-1
Then test:
curl.exe -6 https://your-domain.com
curl.exe -4 https://your-domain.com
If curl -6 works but curl -4 fails, put CloudFront in front or keep IPv4 at the edge.
High-impact tips
Tip 1: Delete idle Elastic IPs aggressively
Idle EIPs are pure waste. They cost the same hourly rate as in-use public IPv4 addresses.
Tip 2: Never put public IPv4 on ECS tasks
For ECS/Fargate, prefer:
assignPublicIp = DISABLED
subnets = private dual-stack subnets
ingress = ALB only
egress = egress-only IGW + VPC endpoints + limited NAT64
Tip 3: Do not deploy one NAT Gateway per AZ unless the workload deserves it
Multi-AZ NAT is highly available, but it multiplies hourly cost. For production, you may need it. For dev, staging, preview, labs, and low-risk workloads, one NAT Gateway or scheduled NAT can be enough.
Tip 4: Add VPC endpoints before blaming NAT
If ECS pulls images, writes logs, fetches secrets, or talks to S3 through NAT, your architecture is leaking money.
Tip 5: Use CloudFront as the IPv4 compatibility layer
The clean long-term pattern is:
IPv4 compatibility at CloudFront
IPv6-first inside AWS
Private-only workloads
No public IPv4 on instances
Minimal NAT
What not to do
Do not make everything IPv6-only blindly.
Avoid these mistakes:
| Mistake | Why it hurts |
|---|---|
| Removing IPv4 before checking dependencies | Some AWS services, third-party APIs, or packages may still need IPv4 |
| Using NAT64 for all traffic | You still pay NAT Gateway charges |
| Making IPv6 resources publicly reachable by accident | IPv6 addresses are globally unique; security groups matter |
| Forgetting DNS AAAA records | IPv6 exists but users cannot reach it |
| Removing public IPv4 from ALB using OIDC/Cognito auth | AWS documents a possible HTTP 500 issue |
| Ignoring logs | You need to know how much traffic is IPv4 vs IPv6 |
Final architecture rule
The best cost-optimized VPC is not “IPv6-only everywhere.â€
It is:
IPv6-first
private-by-default
CloudFront at the edge
ALB without public IPv4 where possible
egress-only IGW for IPv6
VPC endpoints for AWS services
NAT64 only for legacy IPv4
zero idle Elastic IPs
That is the architecture that can cut VPC networking cost aggressively without sacrificing production stability.
References
- Tarification d’Amazon VPC
- Enable outbound IPv6 traffic using an egress-only internet gateway - Amazon Virtual Private Cloud
- DNS64 and NAT64 - Amazon Virtual Private Cloud
- SetIpAddressType - Elastic Load Balancing
- Enable IPv6 for CloudFront distributions - Amazon CloudFront
- Amazon CloudFront announces support for IPv6 origins - AWS
- Access AWS services through AWS PrivateLink - Amazon Virtual Private Cloud
- AWS services that support IPv6 - Amazon Virtual Private Cloud