← Back to home

What a NAT Gateway really costs — and how to schedule it

The NAT Gateway is the most expensive thing in most non-production VPCs that nobody looks at. It has no stop button, its charge is decoupled from traffic, and high-availability guidance quietly multiplies it per Availability Zone. Here is the arithmetic and the only mechanism that actually reduces it.

The two charges

A NAT Gateway bills on two axes in us-east-1:

Traffic that crosses an Availability Zone boundary also incurs standard inter-AZ data transfer (on the order of $0.01/GB per direction — TODO(verify)), but for a dormant environment the number that matters is the first one: the hourly charge you pay for nothing.

The trap

The hourly charge is fixed. An environment that is completely idle overnight — zero data processed — still pays the full $0.045/hour. Utilization-based instincts do not apply; there is no scale-to-zero.

What a dormant multi-AZ setup burns

AWS's own high-availability guidance is one NAT Gateway per Availability Zone, so that a zone failure does not take out egress for the others. That is sound architecture — and it means the fixed hourly charge is paid per zone. For an environment that is only genuinely used ~45 hours of the 168-hour week, here is the hourly-charge cost of leaving the gateways up 24/7 versus scheduling them down outside working hours (us-east-1, hourly charge only):

NAT GatewaysAlways-on / month~45 hrs/week scheduledMonthly saving
1 (single-AZ)$32.40$8.68$23.72
2 (two-AZ)$64.80$17.36$47.44
3 (three-AZ)$97.20$26.03$71.17

The math is $0.045 × 720 hours for always-on, and $0.045 × ~193 hours (45 hours/week over a 30-day month) for the scheduled case, per gateway. Data processing is on top and is genuinely usage-based, so it largely disappears on its own when the environment is idle — the hourly charge is the part scheduling recovers.

Why you can't just stop it

Unlike EC2 and RDS, a NAT Gateway exposes no stop/start. The API surface is create-nat-gateway and delete-nat-gateway and nothing in between. To stop paying for an idle gateway you must delete it, and to bring the environment back you must create a new one — a new gateway with a new ID — then repair the route tables that pointed at the old one.

One detail makes this tractable: the Elastic IP. A NAT Gateway's public address is an EIP you allocate. If you keep the EIP allocation when you delete the gateway, you can re-associate the same address on the replacement, so anything downstream that allowlists your egress IP keeps working across the cycle.

Note

Since 1 February 2024, AWS charges $0.005/hour for every public IPv4 address, including in-use and idle Elastic IPs — about $3.60/month per address. Keeping the EIP allocated between cycles costs this whether the gateway is up or not, and it is far cheaper than the $32.40/month gateway it preserves. TODO(verify current public IPv4 rate)

Scheduling a NAT Gateway: the delete/recreate cycle

The off-window action deletes the gateway; the on-window action recreates it and re-points the route. The shape of it, in the AWS CLI:

# --- OFF window: tear down, keep the EIP allocation ---
aws ec2 delete-nat-gateway --nat-gateway-id nat-0abc123
aws ec2 wait nat-gateway-deleted --nat-gateway-id nat-0abc123
# the route to 0.0.0.0/0 via nat-0abc123 is now blackholed; leave or remove it

# --- ON window: recreate in the same subnet, reuse the same EIP ---
NAT_ID=$(aws ec2 create-nat-gateway \
  --subnet-id subnet-0public456 \
  --allocation-id eipalloc-0kept789 \
  --query 'NatGateway.NatGatewayId' --output text)
aws ec2 wait nat-gateway-available --nat-gateway-id "$NAT_ID"

# repoint the private route table at the new gateway id
aws ec2 replace-route \
  --route-table-id rtb-0private012 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id "$NAT_ID"

That is the happy path for one gateway. A safe implementation has to handle the parts that bite:

This orchestration — waiters, per-route-table repointing, EIP reuse, and doing it on a timezone-aware schedule — is exactly what Uptime Scheduler runs for NAT Gateways tagged for scheduling, inside your own account.

FAQ

How much does a NAT Gateway cost per month?

About $32.40/month per gateway in us-east-1 for the hourly charge alone ($0.045 × 720), plus $0.045/GB processed. A three-AZ HA setup is roughly $97.20/month before any data processing.

Can you stop a NAT Gateway to save money?

No — there is no stop API. The only lever is delete-and-recreate, preserving the Elastic IP and repointing the affected route tables.

Why are NAT Gateway costs so hard to notice?

The charge is fixed and traffic-independent, it hides under the generic EC2-Other usage type in Cost Explorer, and HA designs multiply it per AZ. An idle environment shows almost no data processing while still paying the full hourly charge on every gateway.

See how many idle gateways you're paying for

upscan is our free CLI — run upscan --resources nat --region us-east-1 and it lists your NAT Gateways with their traffic and monthly cost. No signup, no account. It just tells you the number.