← Blog/IPv6 Cost Hacks for AWS VPC: How to Cut VPC Networking Bills Dramatica…
Networking

IPv6 Cost Hacks for AWS VPC: How to Cut VPC Networking Bills Dramatically

May 20, 2026·10 min read

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.

AWSCost OptimizationNetworking

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:

ResourcePublic IPv4 countApprox monthly IPv4 cost
3 public EC2 instances3$10.80
1 public ALB, usually 2 AZs2$7.20
1 NAT Gateway Elastic IP1$3.60
4 forgotten idle EIPs4$14.40
Total10$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:

WorkloadGood fit?Notes
Internal tools used by IPv6-capable networksYesExcellent cost reduction
API consumed by modern cloud clientsYesTest clients first
Public website with unknown usersMaybeSome users still lack IPv6
ALB using Cognito/OIDC authRiskyAWS documents IPv4 dependency
Behind CloudFrontStrong optionCloudFront 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:

DestinationBetter option
S3Gateway VPC Endpoint
DynamoDBGateway VPC Endpoint
CloudWatch LogsInterface VPC Endpoint
ECR APIInterface VPC Endpoint
ECR Docker registryInterface VPC Endpoint
Secrets ManagerInterface VPC Endpoint
SSMInterface VPC Endpoint
STSInterface 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:

ItemMonthly 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:

ItemMonthly 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:

MistakeWhy it hurts
Removing IPv4 before checking dependenciesSome AWS services, third-party APIs, or packages may still need IPv4
Using NAT64 for all trafficYou still pay NAT Gateway charges
Making IPv6 resources publicly reachable by accidentIPv6 addresses are globally unique; security groups matter
Forgetting DNS AAAA recordsIPv6 exists but users cannot reach it
Removing public IPv4 from ALB using OIDC/Cognito authAWS documents a possible HTTP 500 issue
Ignoring logsYou 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