Public vs Private vs Elastic IP
Every EC2 (Elastic Compute Cloud) instance you launch gets at least one IP address, and many get two: a private one and a public one. These addresses behave very differently, and confusing them is one of the most common reasons a beginner’s server “stops working for no reason” after a reboot. This page explains the three kinds of IP addresses on EC2 — private, auto-assigned public, and Elastic — what each is for, and the classic gotcha that trips people up.
What an IP address actually is here
An IP address (Internet Protocol address) is just a number that identifies a machine on a network. On AWS, an EC2 instance lives inside a VPC (Virtual Private Cloud — your own isolated network in the cloud). Inside that network it always has a private IP. To be reachable from the public internet, it also needs a public IP.
The key idea is ownership and stability: some addresses stay the same for as long as the instance exists, some change when you stop and start it, and one type you can permanently reserve. Getting this right is the difference between a stable server and one that silently disappears.
Private IP addresses
A private IP is the address your instance uses inside its VPC. It comes from the range of the subnet you launched into (for example, a subnet with the block 10.0.1.0/24 hands out addresses like 10.0.1.45). Private IPs are not routable on the public internet — other AWS resources in the same network reach the instance through them.
The important property: a private IP is persistent for the life of the instance. It does not change when you stop and start the instance. It only goes away when you terminate (permanently delete) the instance.
When to use it: for all internal traffic — an app server talking to a database, instances behind a load balancer, or anything inside your VPC. Keeping traffic on private IPs is cheaper and more secure because it never leaves AWS’s network.
When NOT to rely on it: anything that must be reached from the internet. Private IPs are unreachable from outside the VPC.
Auto-assigned (dynamic) public IP addresses
When you launch an instance into a subnet that has “auto-assign public IPv4” turned on, AWS gives the instance a public IP from Amazon’s shared pool. This lets you SSH in or serve a website immediately, with no extra setup.
The catch — and this is the big gotcha — is that this address is dynamic. It is borrowed, not owned. You lose it and get a brand-new one whenever you:
- Stop and then start the instance, or
- Terminate the instance.
A simple reboot keeps the address, but a stop/start does not.
Gotcha: If you point a DNS record, a firewall allow-list, or a friend’s
sshconfig at an auto-assigned public IP, it will break the next time you stop and start the instance — because that exact problem is what Elastic IPs (or a load balancer / DNS name) are designed to solve.
When to use it: short-lived, throwaway, or development instances where you don’t care if the address changes — and instances that never stop (or only ever reboot).
When NOT to use it: any production server that other systems connect to by IP.
Elastic IP addresses
An Elastic IP (a permanent, static public IPv4 address that you own) is allocated to your account, not to a single instance. You reserve it once, then associate it with whichever instance you like. Because you own it, it stays exactly the same across stop/start cycles, and you can even move it to a replacement instance during a failover.
When to use it: a production server that must keep one fixed public IP — a mail server, a VPN endpoint, or anything an external partner has allow-listed by address.
When NOT to use it: if a DNS name or a load balancer would do the job better (it usually does — see the tip below). Don’t hoard Elastic IPs you aren’t using.
Cost tip: Since February 2024, AWS charges for all public IPv4 addresses — about $0.005 per hour (roughly $3.60 per month) each, whether the IP is an Elastic IP or an auto-assigned one, attached or not. There is no longer a “free while attached” discount. Release any Elastic IP you no longer need to stop the charge.
Side-by-side comparison
| Property | Private IP | Auto-assigned public IP | Elastic IP |
|---|---|---|---|
| Reachable from internet | No | Yes | Yes |
| Survives reboot | Yes | Yes | Yes |
| Survives stop/start | Yes | No (changes) | Yes |
| You can move it between instances | No | No | Yes |
| You own / reserve it | n/a | No | Yes |
| Typical use | Internal traffic | Dev / throwaway | Stable production endpoint |
| Cost (2026) | Free | ~$3.60/mo | ~$3.60/mo |
How to give an instance a fixed public IP
Using the AWS Management Console
- Open the EC2 console and choose Network & Security → Elastic IPs in the left menu.
- Click Allocate Elastic IP address, leave Amazon’s pool of IPv4 addresses selected, and click Allocate.
- Select the new address (for example
eipalloc-0a1b2c3d), then choose Actions → Associate Elastic IP address. - Set Resource type to Instance, pick your instance
i-0a1b2c3d4e5f, and click Associate. - Your instance now keeps this public IP permanently, even after stop/start.
Using the AWS CLI
# 1. Allocate a new Elastic IP from Amazon's pool
aws ec2 allocate-address --domain vpc
Output:
{
"PublicIp": "52.207.18.244",
"AllocationId": "eipalloc-0a1b2c3d",
"Domain": "vpc"
}
# 2. Associate it with your instance
aws ec2 associate-address \
--instance-id i-0a1b2c3d4e5f \
--allocation-id eipalloc-0a1b2c3d
Output:
{
"AssociationId": "eipassoc-0a1b2c3d"
}
When you no longer need it, release it so the hourly charge stops:
aws ec2 release-address --allocation-id eipalloc-0a1b2c3d
Reserving one with infrastructure as code
If you manage infrastructure with Terraform, an Elastic IP and its association are two small resources:
resource "aws_eip" "web" {
domain = "vpc"
tags = { Name = "web-static-ip" }
}
resource "aws_eip_association" "web" {
instance_id = "i-0a1b2c3d4e5f"
allocation_id = aws_eip.web.id
}
Best Practices
- Use private IPs for all traffic that stays inside your VPC — it is free, faster, and more secure than routing through public addresses.
- Treat auto-assigned public IPs as disposable; never pin DNS, firewall rules, or external integrations to them.
- Prefer a DNS name or load balancer over a raw Elastic IP. A load balancer gives you a stable DNS endpoint, health checks, and scaling — and avoids per-IP charges on every instance.
- Reserve an Elastic IP only when you genuinely need a single fixed public IPv4 address (mail, VPN, allow-listed partner).
- Release unused Elastic IPs promptly — since 2024 every public IPv4 address is billed whether attached or not.
- Consider IPv6, which AWS does not charge for, when your clients support it.
- Tag every Elastic IP with an owner and purpose so unused ones are easy to find and clean up.