The General Synopsis
Over the last year or so, I've been poking my head into online forums such as Reddit, Discord chats and more, seeing the question be raised around "What is an IGW", "How do they work?", "Why use a NAT gateway when I can use an IGW?" and more.
When coming across these questions, I typically give a general overview of how these differentiate and their inner workings.
With that said, I wanted to put together an article detailing what these are, the key differences and when/ where these should be used.
What is an Internet Gateway (IGW)?
At its core, an Internet Gateway in AWS is a resource that allows public internet access to and from the internet for your VPC and it's containing resources.
An IGW sits right at the edge of your VPC. It's a resource you configure that sits between your VPC and the AWS Cloud (region) itself. Internet Gateways allow resources on public subnet's in your VPC the ability to receive an IP address for public connectivity.

Resources like EC2 instances (for example) never receive public IP addresses directly. It's provided to you and mapped to a network interface. This public IP is not visible to the EC2 instance itself, but can be found by calling the meta-data API curl -s http://169.254.169.254/latest/meta-data/public-ipv4
, from the EC2 instance itself (requires IMDSv2 to be set to "optional" in the EC2 console, unless you have correctly set up v2).

So how do IGW's Work?
At it's simplest to understand, Internet Gateways provide a one-to-one NAT. The Internet Gateway contains a one-to-one NAT translation from the private IP address of a resource to a public IP address.


The VPC router (invisible to us as users, but programmable via VPC Route Tables) passes traffic destined to the internet to the IGW. This assumes you have a default route in your VPC Route Table destined to the IGW (0.0.0.0/0 > Internet Gateway).
The VPC router being the first usable IP address in the provided subnet (a whole topic in itself). When traffic is then received to that public IP, IGW then send it back to the VPC router for processing and eventually sent to the resource (it's interface).
- AWS associates the public IP with the instance using one-to-one NAT.
- Outbound packets from the instance are translated to the public IP.
- Inbound packets to the public IP are routed to the instance's private IP.
What is a NAT Gateway?
NAT Gateways are a fully managed AWS service that lets resources in a private subnet start conversations with the outside world (the public internet, other VPCs, or on-premises networks) while stopping anything on the outside from starting a conversation with them. It’s an “egress-only, stateful doorway” for your private workloads. AWS now offers two connectivity types:
- Public NAT Gateway – lives in a public subnet, is mapped to a single Elastic IP (public IP), and fronts all traffic from the private subnets that route to it.
- Private NAT Gateway – lives in a private subnet and performs NAT inside your VPC address space, handy for overlapping CIDRs, hybrid networks, or VPC-to-VPC traffic that must stay off the public internet.
Resources (for example, an EC2 instance in a private subnet) never see the NAT GW’s IP. They keep their private IP, but any outbound packet that hits the NAT GW is rewritten so it appears to come from the Elastic IP (public NAT) or the NAT GW’s private IP (private NAT). When the return packet arrives, the NAT GW tracks the connection state and maps it back to the original source IP/port inside your subnet.
How do NAT Gateways work?
Many-to-one NAT. Unlike an Internet Gateway’s 1-to-1 public IP mapping, a NAT GW multiplexes thousands of simultaneous connections behind a single address. Here’s the life-cycle of an outbound request:
- Default route: In the private subnet’s route table you point
0.0.0.0/0
(and optionally::/0
) to the NAT GW’s ENI. - Connection tracking: The NAT GW opens a stateful entry, translating source IP/port to its own IP/port tuple.
- Return traffic: Reply packets hit the NAT GW first, which reverses the translation and forwards them to the VPC router, which then delivers them to the instance.
- Ephemeral only: Unsolicited inbound connections are dropped because there’s no matching state entry. Egress only.
Where Should a NAT Gateway be used?
There are many situations where an IGW is best used and vice versa, a NAT Gateway. Below, we will give a few examples of where NAT Gateways are best used.
Keeping instances private while still reaching the internet
Many workloads you provision (databases, ECS/Fargate tasks, Lambda functions in a VPC, batch workers, patch servers, etc.) must never be reachable from the public internet. Giving them a public IP, even with restrictive security-group rules, still violates the “no public address” requirement found in PCI-DSS, ISO-27001, and other corporate policies. A NAT Gateway lets those private-IP-only resources fetch patches, call SaaS APIs, or push telemetry without exposing any inbound path.

One egress IP to allow-list
Partners often ask you to “allow traffic only from X.X.X.X”. If every instance has its own public IP, you may end up having to maintain dozens/ hundreds of addresses; with a NAT Gateway you hand them one Elastic IP and call it done. (If you need full isolation you can deploy multiple NGWs and route specific workloads through dedicated ones.)

Avoiding Public-IP Sprawl (and conserving IPv4)
AWS public IPv4 addresses are a scarce, and billable resource. By funnelling hundreds of private hosts through a single NAT Gateway (and therefore a single Elastic IP) you minimise both address consumption and the risk of running out of attachable public IPs in the account.
Built-in scalability & resilience
A managed NAT Gateway:
- Scales to 100 Gbps per AZ automatically.
- Is highly available inside its AZ.
- Requires only one line in a route table; no iptables, no user-data scripts.
For full AZ resilience you create one NGW per AZ and let each private subnet route to the NGW in its own zone (so a zonal failure doesn’t black-hole traffic).
Security-group Limits vs Architectural Guarantees
Security groups are great stateful firewalls, but:
- They can be accidentally opened (an “allow 0.0.0.0/0” rule is one click away).
- An attacker still sees the public IP and can brute-force SG combinations or hammer you with SYN floods (you pay for the bandwidth).
- Compliance scans often flag the mere presence of a public IP, independent of SG settings.
With a NAT Gateway the address simply isn’t there, eliminating an entire attack vector.
When not to use a NAT Gateway
- Public-facing servers (web, API, bastion) that legitimately need inbound access. Give them a public IP + IGW, but also consider utilising ELBs (Elastic Load Balancers).
- IPv6-only architectures - NAT is an IPv4 construct; IPv6 traffic can flow through the IGW directly with SGs/NACLs. Or with patching of instances and more, we can utilise Egress-only Internet Gateways.
- Tiny, bursty environments where the per-hour NGW cost outweighs benefits, you can run a “NAT instance” instead, accepting the ops burden.