Business Challenge
Six posts have been about ranges. This one is about the addresses drawn from them, and it turns on a distinction that the vocabulary actively obscures. Static and ephemeral external IP addresses behave and appear the same in most contexts — which is true, and is why the places they differ catch people.
The useful reframing is that static and ephemeral are not two levels of permanence. They are two different bindings. An ephemeral address is bound to the instance running; a static address is bound to the instance existing. Every behavioural and billing difference follows from that one fact, including the one nobody predicts: the state where nothing is running is the most expensive state an address can be in.
If the address was static, you are paying more. Google Cloud considers a static external IP address as in use if it is associated with a VM instance whether the instance is running or stopped — but if the instance is deleted or if the IP address is dissociated from the instance, Google Cloud considers the static IP address as not in use. And not in use is the dear rate: you are charged at a higher rate for unassigned static external IP addresses than you are for static and ephemeral external IP addresses that are in use.
Correct approachTreat deleting a resource as the moment to decide the fate of its reserved address, in the same change. If you will rebuild onto the same address, keep it and know it costs double in the interim. If you will not, release it — otherwise the cost rises precisely when the thing it served stops existing.
That works for a static address and fails for an ephemeral one. For an ephemeral IP address, Google Cloud considers the address as in use only when the associated VM instance is running, and when the instance is stopped or deleted, Google Cloud releases the ephemeral IP address and no longer considers it as in use. Released means gone — the address returns to the pool and the VM comes back with a different one.
Correct approachIf anything outside your control references the address — a DNS record you do not manage, a partner's allowlist, a firewall rule somewhere else — it has to be static before the first stop, not after. You can reserve new external IP addresses or promote existing ephemeral external IP addresses, so an address already in use can be made static in place without renumbering anything.
It will not. An external IPv4 address on a VM is Compute Engine VM network interfaces (in a one-to-one NAT configuration) — the address is mapped to the instance by the network, not configured on it. The guest sees its internal address only. The same applies to naming: Google Cloud automatically resolves the fully qualified DNS name (FQDN) of an instance to the internal IP addresses of the instance, and internal DNS names work only within the instance's VPC network.
Correct approachRead the external address from the resource metadata rather than from inside the operating system, and never assert the instance's public identity from anything the guest reports. This is the same shape as #66's silent gateway — a real address with no local evidence of itself.
Architecture
Two axes, independent of each other. Reachability is the first and lifecycle is the second, and conflating them is what makes the pricing table look random.
Axis one: reachability
External IP addresses are publicly advertised, meaning they are reachable by any host on the internet, and external IP addresses must be publicly routable IP addresses. Internal is the complement: internal IP addresses cannot be reached from the internet and are not publicly routable.
"Internal" is broader than it sounds, and the definition is worth having exactly, because it decides what a private address can reach. Internal addresses are local to a VPC network, a VPC network connected by using VPC Network Peering, or an on-premises network connected to a VPC network by using Cloud VPN, Cloud Interconnect, or a Router appliance. That is the whole hybrid estate — so "internal" means private to your connected world rather than private to one network, which is precisely why #63's warning about overlapping on-premises ranges mattered.
One tier note that is easy to miss and has a cost implication: internal IP addresses are always Premium Tier. There is no Standard Tier option for internal traffic, so the tier decision from earlier in this series applies to external paths only.
Axis two: lifecycle
Both reachability types can be either lifecycle type, which is the part the external-facing documentation tends to bury. Internal addresses are assigned one of two ways: Compute Engine automatically assigns a single IPv4 address from the primary IPv4 subnet ranges, or you assign a specific internal IPv4 address when you create a compute instance, either by using a reserved static internal IPv4 address or by specifying a custom ephemeral internal IPv4 address. And you can plan ahead — you can also reserve a static internal address from the subnet's IPv4 or IPv6 range and later assign it to an instance.
| Event | Ephemeral external | Static external |
|---|---|---|
| VM running | In use | In use |
| VM stopped | Released — the address is lost | Retained, and still counted in use |
| VM deleted | Released | Retained as reserved, not in use |
| Address dissociated | No such state | Retained as reserved, not in use |
| Delete and re-create the resource | New address | You can use the same IP address for the same resource |
The second row is where the two bindings separate most cleanly, and it is the operationally important one. Stopping a VM is routine — overnight shutdowns, scaling to zero, maintenance. On a static address nothing happens and nothing changes price. On an ephemeral address the address is gone, and the breakage shows up wherever something external remembered it.
The reserved-but-unattached state is worth naming as a thing you can create deliberately, because it is how you move an address between resources: unassigning an IP address removes it from the resource but keeps the IP address reserved. That is the intended mechanism; it is also the state that costs the most, so it should be a transition rather than a resting place.
Why This Architecture Holds Up
Internal addressing is free, in both lifecycle flavours: there is no charge for static or ephemeral internal IP addresses. Everything below is about external IPv4 on a VM, which is the narrow surface that actually bills.
| State | Rate |
|---|---|
| Static and ephemeral IP addresses in use on standard VM instances | $0.005 per hour |
| Static and ephemeral IP addresses in use on preemptible and Spot VM instances | $0.0025 per hour |
| Static IP address (assigned but unused) | $0.01 per hour |
| Static and ephemeral IP addresses attached to forwarding rules, or used as a public IP for a Cloud VPN tunnel | No charge |
| All internal addresses, static or ephemeral | No charge |
An unused reserved address costs $0.01 an hour against $0.005 for one doing work — exactly twice. Over a 730-hour month that is $7.30 for an address attached to nothing, against $3.65 for one serving a running VM. The incentive is deliberate and it points the right way: the platform is charging you to stop hoarding addresses. But it means an idle reservation is not a cheap option being held open; it is the dearest line in this table.
Two exemptions are generous enough to change designs. You are not charged for static external IP addresses that are assigned to forwarding rules — so a load balancer's front-end address is free, which is a real argument for putting a load balancer in front of a service rather than giving the VM a public address. And IPv6 is largely outside the billing entirely: you are not charged for external IPv6 address ranges that are assigned to subnets or for external IPv6 addresses that are assigned to VM instances.
The reason to have fewer external addresses at all
Cost is the weaker argument. The documentation leads with the other one: removing external IP addresses from compute instances makes it more difficult for attackers to reach the instances and exploit potential vulnerabilities. That is the whole case in one line, and it is sharpened by the fact that only resources with an external IP address can directly communicate with resources outside of the VPC network — so an external address is not a convenience bolted onto a VM, it is the entire mechanism by which that VM becomes reachable from outside.
There is also a traffic charge separate from the address charge: communicating with a resource using an external IP address can cause additional billed charges. The address rent is the small part.
The one-to-one NAT consequence
A VM's external IPv4 address is a mapping rather than an interface configuration — the documentation lists the use as a one-to-one NAT configuration, and the API field that creates it is an access config of type ONE_TO_ONE_NAT. The instance's own view of its networking never includes the public address.
That has a practical edge beyond trivia. Any software that discovers its own address from the operating system — a service registering itself, a certificate request, a config file generated at boot — will discover the internal one. And the single global-scope exception is worth knowing for contrast: global external IPv4 addresses are internet accessible anycast external IPv4 addresses for global load balancing, which are not attached to an instance at all. Everything else is regional, because when you associate an address with a regional resource, such as a VM, Google Cloud labels the address as regional.
Unassigning a static external address from an instance — the supported way to move it — carries a limitation: this procedure is supported for dual-stack instances, but not IPv6-only instances. If IPv6-only is in the plan, address portability is not the same operation there.
Key Architecture Decisions
| Situation | Decision | Because |
|---|---|---|
| Anything outside your control references the address | Static, before the first stop | An ephemeral address is released when the instance stops, not only when it is deleted. |
| An address is already live and must become fixed | Promote it in place | Promotion makes an existing ephemeral address static without renumbering. |
| Deleting a resource that has a reserved address | Decide the address in the same change | Deletion flips it to the double rate; nothing will remind you. |
| Service needs to be reachable from the internet | Load balancer, not a VM external address | Forwarding-rule addresses are free, and the VM stays unreachable directly. |
| Internal addressing of any kind | Reserve static freely | Internal addresses cost nothing in either flavour. |
| Software needs to know its own public address | Read it from resource metadata | One-to-one NAT means the guest OS never sees it. |
| IPv6 external addressing | Treat the address cost as zero | External IPv6 on subnets and VM instances is not charged. |
The one to look at today
Run gcloud compute addresses list and read the status column. Every row showing RESERVED rather than IN_USE is an address attached to nothing, billing at double, and invisible to any inventory built from instances — which is where most people look. For each, the question is only whether a specific thing still needs that specific address. Where the answer is no, releasing it is the single cheapest cost action in this whole block of the series.
Closing Thought
The pricing here reads as perverse until you see what it is pricing. It is not charging for the address being used; it is charging for the address being held. An address attached to a running VM and an address attached to a stopped VM cost the same, because in both cases something identifiable owns it. An address attached to nothing costs double, because the only thing keeping it out of the pool is your intention to use it later. The platform is pricing the option, and options are more expensive than commitments.
That framing makes the vocabulary make sense too. "Static" and "ephemeral" sound like a judgement about how long the address lasts, which invites you to read static as better. They are really a statement about what the address is attached to: the instance's existence, or the instance's execution. Seven posts into addressing, the reliable move is still the same — find the event the behaviour is bound to, and the documentation stops being a list of exceptions.
#68 leaves addresses for the thing that moves packets between them: routes — system-generated and custom, what Google Cloud creates for you, and what it will not.
Comments