AWS Private vs Public IP Addresses: EC2, Elastic IPs, and When to Use Each
Every EC2 instance gets a private IP address the moment it launches. Whether it also gets a public IP depends on the subnet settings and what you choose at launch. The critical difference: public IPs are ephemeral. They change every time you stop and start an instance. Elastic IPs solve this with a static address your account owns. Getting this wrong is one of the most common causes of broken DNS records and failed partner integrations in AWS.
AWS now charges for all public IPv4 addresses, including those attached to running EC2 instances. That changes the calculus for when to assign a public IP at all, and makes private-subnet architectures even more worth understanding.
Simple explanation
Office building analogy: Think of a building with internal phone extensions and direct outside lines. A private IP is your internal extension — only colleagues inside the building can dial it. A public IP is an outside line borrowed from the phone company’s pool. If you leave the building (stop the instance), they reassign it to someone else. An Elastic IP is a dedicated outside line your company owns outright. It follows you wherever you go, and you pay a monthly fee whether you use it or not.
Three IP types, three very different behaviors:
Private IP: VPC-internal only. Every instance gets one. Permanent for the life of the instance. No internet reachability.
Public IP: Internet-routable. Drawn from a shared AWS pool. Returns to the pool when the instance stops, so it changes on restart.
Elastic IP: Internet-routable. Reserved to your account. Static, survives stop/start, can be moved between instances. AWS charges for it in all states.
An Application Load Balancer with a stable DNS name is a better external endpoint than pinning traffic to any instance IP. Load balancers give you health checks, multi-AZ redundancy, and TLS termination that no IP address can provide.
Why this matters in real AWS environments
Three operational consequences come up repeatedly:
DNS breaks after stop/start. If you put your instance’s public IP in a DNS record and then stop the instance overnight, the IP changes. Your DNS record now resolves to an address AWS has likely given to someone else. Use a Route 53 alias to a load balancer, or an Elastic IP, to avoid this.
Partner firewall allowlists break after stop/start. External partners often allowlist the source IPs of traffic coming from your environment. If your EC2 instance gets a new public IP after a restart, traffic from that instance gets blocked at the partner’s firewall. Elastic IPs exist precisely to solve this.
Backend instances should not be internet-exposed. Database servers, internal API services, and worker processes have no reason to hold a public IP. Giving them one widens your attack surface unnecessarily. Place them in private subnets with no public IP assignment, and route outbound traffic through a NAT Gateway if they need it.
How IP addressing works in AWS
When you launch an EC2 instance, AWS assigns it a private IPv4 address from the CIDR range of the subnet it lands in. That address is attached to the instance’s primary elastic network interface (ENI) and stays there until the instance is terminated.
Whether the instance also gets a public IPv4 address depends on two things: the subnet’s auto-assign public IPv4 setting, and whether you override that setting at launch. Public subnets typically have auto-assign enabled. Private subnets have it disabled. You can override the subnet default at launch time either way.
This setting lives on the subnet, not the instance. You can change it per subnet in the VPC console. Any instance you launch into that subnet will inherit the setting unless you override it at launch. Disabling it across private subnets is one of the easiest ways to reduce unnecessary public IPv4 charges.
A key distinction: the public IP drawn from the pool is not owned by your account. AWS maps it to the instance’s primary private IP at the network edge using NAT. When you stop the instance, AWS reclaims it. When you restart, you get a different address from the pool.
An Elastic IP, by contrast, is allocated to your account and stays there until you explicitly release it. You can associate it with any EC2 instance or network interface, disassociate it, and reassociate it whenever needed. It is static from the perspective of anything pointing to it externally.
Internet access still requires more than just a public IP. The VPC needs an internet gateway attached, the route table for the subnet needs a default route pointing to that gateway, and security groups and network ACLs need to allow the relevant traffic.
Private IP addresses
Private IPs come from RFC 1918 address space — ranges not routable on the public internet:
10.0.0.0/8172.16.0.0/12192.168.0.0/16
Every EC2 instance gets at least one private IP from its subnet’s CIDR range. That address stays the same through stop/start cycles and is released only when the instance is terminated.
Traffic between resources in the same VPC travels entirely over the AWS internal network. It never touches the public internet, which means it is faster, more secure, and free of data-transfer charges within the same Availability Zone.
An instance can hold multiple private IPs. Secondary private IPs are useful when you need one instance to serve multiple applications, each with its own address, or when you want to migrate a specific IP to a replacement instance during a failover.
Good for: internal service communication, database connections, inter-instance calls, anything that should never be internet-reachable.
Public IP addresses
A public IP address lets an instance communicate directly with the internet, inbound and outbound. AWS assigns it from a shared pool. You do not choose which specific address you get.
Public IPs are ephemeral. Stop an EC2 instance and its public IP goes back into the pool. When you start the instance again, it draws a new address. A reboot does not change the public IP. Only a full stop/start cycle does.
AWS now charges for all public IPv4 addresses, including those attached to running EC2 instances. This applies to standard public IPs and Elastic IPs alike. Before assigning a public IP, confirm the instance actually needs direct internet reachability. Many workloads behind a load balancer do not.
Whether an instance gets a public IP depends on the subnet’s auto-assign setting and your choice at launch. You can override the subnet default at launch, but you cannot add or remove a standard public IP after launch. For that, you need an Elastic IP.
When a public IP is appropriate: bastion/jump hosts, single-instance development environments, or when you need the instance to be directly internet-reachable and the cost and ephemerality are acceptable.
Elastic IP addresses
An Elastic IP (EIP) is a static public IPv4 address that belongs to your AWS account. You allocate it once and it stays yours until you release it. You can associate it with any EC2 instance or network interface, and move it to a different resource at any time without changing the address.
This makes Elastic IPs useful when external systems have your IP hardcoded: partner firewall allowlists, on-premises network rules, legacy integrations that cannot use DNS names. When the underlying instance needs to be replaced, you reassociate the same EIP to the replacement and external dependencies see nothing change.
AWS charges for public IPv4 addresses whether they are associated with a running instance or sitting idle. Idle (unassociated) EIPs face an additional charge on top of that, intentionally, to discourage hoarding a finite public resource. Release any EIP you are not actively using. Check the AWS pricing page for current rates.
If traffic is coming from the internet through an Application Load Balancer, you do not need an EIP on the instances behind it. Use the load balancer’s DNS name as the stable external endpoint. Route 53 alias records pointing to a load balancer are a cleaner and more resilient pattern than pinning traffic to an instance IP. The load balancer can survive instance replacement, scale horizontally, and spans multiple AZs. An Elastic IP cannot do any of that.
Private vs Public vs Elastic IP: comparison table
| IP type | Scope | Changes on stop/start? | Internet reachable? | Best use case | Typical mistake | Cost note |
|---|---|---|---|---|---|---|
| Private IP | VPC-internal only | No | No | Internal service communication, databases, backend apps | Hardcoding a private IP instead of using service discovery or DNS | No charge |
| Public IP | Internet-routable | Yes | Yes | Dev instances, bastion hosts, temporary internet access | Hardcoding in DNS or config (breaks on restart) | Charged per hour (AWS public IPv4 pricing) |
| Elastic IP | Internet-routable | No (static) | Yes | Partner allowlists, stable outbound identity, instance failover | Using an EIP where an ALB DNS name would be better | Charged per hour; additional charge when idle |
Public IP vs Elastic IP: the key difference
Both are public IPv4 addresses reachable from the internet. The difference is ownership and persistence:
- A standard public IP is drawn from AWS’s pool at launch and returned to the pool when the instance stops. You never own it — AWS lends it to you while the instance runs.
- An Elastic IP is allocated to your account and stays there until you release it. It survives instance stop/start and termination. You can reassign it to any resource in the same region.
Both are subject to AWS public IPv4 address charges. The practical reason to prefer an EIP over a standard public IP is stability. If the address must remain constant, only an EIP guarantees that.
When to use each
Internal resource with no internet exposure: use a private IP only. Temporary internet access where IP stability does not matter: use a public IP. Fixed IP required by an external partner or system: use an Elastic IP. Serving web traffic to users at scale: use a load balancer DNS name, not an IP at all.
Use a private IP when:
- The resource only needs to communicate with other resources inside the VPC.
- You are connecting via VPC peering, VPN, or Direct Connect.
- The resource is a database, internal API, queue consumer, or any backend component that should not be directly reachable from the internet.
Use a public IP when:
- The instance needs direct inbound or outbound internet access and the IP does not need to be stable.
- You are running a temporary development or test instance and do not care if the IP changes.
- You can absorb the consequence of IP changes (for example, if you update DNS automatically on restart).
Use an Elastic IP when:
- A partner or external system has your IP hardcoded in a firewall allowlist.
- You need a stable outbound IP identity — for example, if a third-party API requires requests to come from a known, fixed IP.
- You are running a single-instance setup (not behind a load balancer) and need the IP to survive instance replacement.
Use a load balancer DNS name instead when:
- You are serving internet traffic to end users. An Application Load Balancer gives you a stable DNS name, health checks, TLS termination, and horizontal scaling that an Elastic IP cannot.
- You want to route traffic across multiple instances or Availability Zones.
- You are setting up global load balancing with Route 53. The target is a load balancer, not an instance IP.
Real examples
A Node.js API server lives in a private subnet with no public IP. It receives traffic from an Application Load Balancer over its private IP. It makes outbound calls to third-party APIs through a NAT Gateway. Nobody on the internet can reach it directly, and there is no public IPv4 charge on the instance itself.
A single EC2 instance running a personal project has auto-assign public IPv4 enabled. It receives traffic directly on port 443. If the instance is stopped and started, the IP changes. Acceptable here because the developer updates the DNS record manually. Not appropriate for a production site with real users.
A payment processing integration requires all requests to a bank partner to come from a fixed IP. You allocate an Elastic IP, associate it with the EC2 instance handling those requests, and register that EIP with the partner. If the instance needs to be replaced, you reassociate the same EIP to the replacement. The partner’s allowlist never needs to change.
A modern API server is assigned an IPv6 address from the VPC’s IPv6 CIDR block. IPv6 clients reach it directly — no NAT, no Elastic IP needed. For instances that should not accept unsolicited inbound IPv6 connections, an Egress-Only Internet Gateway handles outbound-only IPv6 traffic.
Allocating and associating an Elastic IP
# Allocate an Elastic IP address to your account
aws ec2 allocate-address \
--domain vpc \
--tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=web-server-eip}]'
# Note the AllocationId in the output (e.g., eipalloc-0123456789abcdef0)
# Associate the Elastic IP with an EC2 instance
aws ec2 associate-address \
--instance-id i-0123456789abcdef0 \
--allocation-id eipalloc-0123456789abcdef0
# Disassociate (remove from instance without releasing the EIP)
aws ec2 disassociate-address \
--association-id eipassoc-0123456789abcdef0
# Release an Elastic IP you no longer need (stops the charge)
aws ec2 release-address \
--allocation-id eipalloc-0123456789abcdef0IPv6 in AWS
AWS supports IPv6 across most services. You can assign an IPv6 CIDR block to your VPC and subnets, and EC2 instances can receive globally routable IPv6 addresses.
Unlike IPv4, there is no RFC 1918-style “private” IPv6 range. Every IPv6 address in AWS is globally routable by design. That does not mean all IPv6 traffic is uncontrolled. Route tables, security groups, and network ACLs still gate what can reach the instance. An IPv6 address alone does not make an instance reachable from the internet — the VPC needs an internet gateway and appropriate routes.
For instances that need outbound-only IPv6 access without receiving unsolicited inbound connections, AWS provides an Egress-Only Internet Gateway. It is the IPv6 equivalent of a NAT Gateway: outbound traffic flows out, inbound connections are dropped.
IPv6 addresses assigned to EC2 instances do not carry the same per-address charge as public IPv4. If you are designing a new workload and want to reduce public IPv4 costs, dual-stack (IPv4 + IPv6) VPCs are worth considering.
Common mistakes
Hardcoding a public IP anywhere — DNS, application config, environment variables, firewall rules — and then stopping the instance. The IP changes, and now everything pointing to it is broken. Use Route 53 pointing to a load balancer DNS name, or use an Elastic IP if a load balancer is not in the picture.
Assigning public IPs to resources that do not need them. Databases, internal APIs, and worker instances in private subnets do not need public IPs. Giving them one costs money and widens your attack surface without benefit.
Assuming “public subnet” means every instance must have a public IP. A public subnet just has a route to an internet gateway. You can place an instance in a public subnet without assigning it a public IP. For example, if it only receives traffic from a load balancer inside the VPC, no public IP is needed.
Using an Elastic IP where an ALB or Route 53-backed endpoint is better. If you are serving end-user traffic, a load balancer gives you health checks, multi-AZ redundancy, and TLS termination. An Elastic IP tied to a single instance is a single point of failure with none of those benefits.
Forgetting to release Elastic IPs after terminating instances. Terminating an EC2 instance disassociates its EIP but does not release it. The EIP stays in your account, idle, accumulating charges indefinitely. After decommissioning instances, audit your Elastic IPs and release any that are unassociated.
Ignoring ongoing public IPv4 cost implications. AWS now charges for all public IPv4 addresses, including those on running instances. The default behavior of auto-assigning public IPs in public subnets carries a real cost. Audit your subnets and disable auto-assign where it is not needed.
Summary
- Every EC2 instance gets a private IP from its subnet’s CIDR range, permanent for the life of the instance.
- Public IPs are ephemeral: they change on every stop/start cycle and are drawn from a shared AWS pool.
- Elastic IPs are static public IPv4 addresses your account owns until you release them, moveable between instances.
- AWS charges for all public IPv4 addresses, including those attached to running instances. Elastic IPs face an additional charge when idle.
- For stable external endpoints serving web traffic, an Application Load Balancer DNS name is almost always better than pinning to an instance IP.
- IPv6 addresses in AWS are globally routable. Use an Egress-Only Internet Gateway for outbound-only IPv6 traffic from private instances.
Frequently asked questions
Does stopping and starting an EC2 instance change its private IP?
No. A private IP stays with the instance for its entire lifetime, released only when the instance is terminated. Only the ephemeral public IP changes on a stop/start cycle.
When should I use an Elastic IP in AWS?
Use an Elastic IP when you need a static public IPv4 address that survives instance replacement. The most common case is when an external partner allowlists your outbound IP, or when you cannot route traffic through a load balancer. For most public-facing workloads, a load balancer DNS name is a better choice than pinning to an Elastic IP.
Do I need a public IP for an instance in a public subnet?
No. "Public subnet" means the subnet has a route to an internet gateway. It does not mean every instance in it must have a public IP. You can place an instance in a public subnet without assigning a public IP if it only needs to receive traffic from a load balancer inside the VPC.
Does AWS charge for public IPv4 addresses?
Yes. AWS charges for all public IPv4 addresses, including those attached to running EC2 instances. Elastic IPs face an additional charge when idle (unassociated or attached to a stopped instance). Check the AWS pricing page for current rates.
Can a private instance reach the internet without a public IP?
Yes, through a NAT Gateway in a public subnet. The NAT Gateway holds a public IP, translates outbound requests, and returns responses to the private instance. The private instance is never directly reachable from the internet.