Business Challenge
This number has appeared in four of the last five posts and been deferred every time. Google Cloud uses the first two and last two IPv4 addresses in each subnet primary IPv4 address range to host the subnet. Four addresses, gone from every primary range, which is the sort of fact you accept as the cost of doing business and stop examining.
Two things make it worth examining. The first is that the overhead is not universal inside the same subnet: Google Cloud lets you use all addresses in secondary IPv4 ranges. If four reservations were a requirement of IP addressing, a secondary range would pay them too. The second is that IPv6 reserves something of an entirely different shape. Read individually against those two facts, the four addresses turn out to be one function, one placeholder, and two inheritances — and knowing which is which changes how you size a subnet.
You cannot, and the documentation is unusually direct about the consequence. Google Cloud software-defined networking reserves a virtual gateway IP address for the primary IP ranges of each subnet in a VPC network — so the address exists. But virtual gateways do not respond to ICMP traffic or decrement IP TTL headers, and therefore a default gateway doesn't respond to ping and doesn't appear when you run traceroute from a VM instance.
Correct approachTake the instruction Google gives, which is a configuration change rather than a workaround: tools that ping the gateway IP address as a connectivity test must be configured so that they don't consider the inability to ping a virtual gateway to be a failure condition. Test reachability against something that answers — a peer instance, a service endpoint — and treat gateway silence as expected rather than diagnostic.
It gives you four. The minimum primary or secondary range size is eight IPv4 addresses, so the longest subnet mask that you can use is /29 — and the first two and last two of those eight are the platform's. Half the range is overhead at the floor — a very different proposition from a /24, which pays exactly the same four addresses out of 256.
Never size a primary range from the address count you need; size it from the count you need plus four, then round up. And treat /29 as a range for something genuinely fixed and tiny, because the proportional overhead at that size makes it the worst value on the scale.
Two of them are, and that is the point — standard is not the same as required. The last address is the broadcast address, reserved in a platform where VPC networks do not support broadcast or multicast addresses within the network and which support IPv4 and IPv6 unicast addresses only. And the second-to-last carries no function at all: this range is reserved by Google Cloud for potential future use.
Correct approachStop reasoning from the names. They describe where the addresses came from historically, not what the platform does with them, and two of the four are unavailable for reasons that are conventional rather than technical. What matters operationally is only the count — four, fixed, per primary range — and that count is a subnet-sizing input, not a networking concept to design around.
Architecture
The documentation lists the four against a worked example, and taking them one at a time is what makes the pattern visible.
| Address | Documented description | In 10.1.2.0/24 |
Does it do anything? |
|---|---|---|---|
| Network address | First address in the primary IPv4 range | 10.1.2.0 from range 10.1.2.0/24 | It names the range. Structural, not assignable by convention. |
| Default gateway address | Second address in the primary IPv4 range | 10.1.2.1 from range 10.1.2.0/24 | Yes — the only one. And it answers nothing you send it. |
| Second-to-last address | Second-to-last address in the primary IPv4 range; this range is reserved by Google Cloud for potential future use | 10.1.2.254 from range 10.1.2.0/24 | Not yet. It is held against a purpose not stated. |
| Broadcast address | Last address in the primary IPv4 range | 10.1.2.255 from range 10.1.2.0/24 | No — the network does not support broadcast. |
The gateway, which is reserved and silent
The one functional reservation behaves in a way that has cost people real time, and #61 flagged it as one of two things that make a healthy network look broken. The address is genuinely allocated — software-defined networking reserves it for the primary range of every subnet — but it is not a device. It does not answer ICMP and it does not decrement TTL, so it is invisible to both of the tools you would reach for to confirm it is there.
There is a detail in the same note that belongs to this post rather than to #61, because it completes the asymmetry: subnet secondary IP ranges don't have a reserved virtual gateway IP address. So the one reservation with a function is also the one that secondary ranges do without — they route through the primary range's gateway, which is consistent with #64's finding that all alias addresses on an interface share the primary address's default gateway.
The broadcast reservation is the clearest case. IPv4 convention makes the last address of a range the broadcast address, and Google Cloud reserves it — in a network that explicitly does not support broadcast. The reservation is real and the capability it names does not exist here. The second-to-last is stranger still, being reserved for potential future use: a documented reservation with no documented purpose. Neither is wrong, and both cost you an address per subnet.
Why secondary ranges settle the question
If the four reservations were structurally necessary, they would apply wherever addresses are allocated. They do not. A secondary range in the same subnet, serving the same VMs through alias IP, reserves nothing — Google lets you use all addresses in it, and it has no reserved gateway either.
That is the whole argument in one comparison. A secondary range is a Google Cloud construct with no inherited convention attached to it, so none of the conventional reservations appear. A primary range is the thing that has to look like a subnet to every tool, operating system and engineer that has ever met one, so it keeps the shape — network address at the bottom, gateway next to it, broadcast at the top — whether or not the platform uses them.
Why This Architecture Holds Up
The IPv6 case is the control experiment, because Google designed this addressing without a legacy to honour. The reservation exists, and it is a different kind of thing entirely: the first and last /96 range of a subnet's internal /64 range cannot be specified manually because Google Cloud reserves the first and last /96 range of a subnet's internal /64 range for system use.
Three differences are worth naming. It reserves ranges, not addresses — a /96 at each end. It gives them one description for both, reserved for system use, with no network-address or broadcast naming and no placeholder held against the future. And everything else remains yours: you can manually specify any other valid /96 IPv6 range from the subnet's internal /64 range to be assigned to your VM network interfaces.
The documented examples are fd20:db8::/96 from range fd20:db8::/64 and fd20:db8:0:0:ffff:ffff::/96 from range fd20:db8::/64. A /64 contains 4,294,967,296 ranges of /96, so reserving two of them removes a proportion with eight zeros after the decimal point. In IPv4 the same instinct — reserve the ends — costs half a /29. The design is the same and the bill is not, because IPv4 ranges are small enough for convention to be expensive.
Which makes this a sizing argument
The operationally useful form of all this is simple arithmetic that the fixed count makes non-obvious. Four addresses is not a percentage; it is a toll paid once per primary range, so its weight is decided entirely by how large the range is.
| Primary range | Addresses | Usable | Reserved |
|---|---|---|---|
/29 (the floor) |
8 | 4 | 4 |
/24 |
256 | 252 | 4 |
/20 (auto mode's size) |
4,096 | 4,092 | 4 |
/8 (the recommended cap) |
16,777,216 | 16,777,212 | 4 |
Auto mode's own table shows this in practice rather than in theory: every automatically created subnet is a /20, and its documented usable band runs 10.128.0.2 to 10.128.15.253 — the four reservations visible as the two addresses missing from each end. At /20 nobody notices. At /29 it is the dominant term.
So this is the cleanest quantitative argument for what #63 recommended on architectural grounds. Google advises grouping applications into fewer subnets with larger ranges because subnet count does not affect routing; the reserved addresses add that every boundary also costs four addresses regardless of how small the thing behind it is. Ten /29 subnets consume 80 addresses of space and yield 40 usable; a single /26 consumes 64 and yields 60. The ten boundaries lose 40 addresses to reservations against the single range’s 4 — and the /26 is smaller, holds more, and has one range to firewall, one to expand, and one to remember.
Key Architecture Decisions
| Situation | Decision | Because |
|---|---|---|
| Sizing any primary range | Required addresses plus four, then round up | The overhead is a fixed count, not a percentage, and it is taken before you get anything. |
Considering a /29 |
Use /28 or larger unless the workload is fixed and tiny |
Half the floor range is platform overhead. |
| Health checks and connectivity tests | Never ping the gateway; configure tools not to treat its silence as failure | Virtual gateways answer no ICMP and decrement no TTL, by design. |
| Capacity planning on alias IP ranges | Count the whole secondary range as usable | Secondary ranges reserve nothing, and have no gateway of their own. |
| Planning IPv6 subnets | Ignore the reservation in the arithmetic | Two /96 ranges out of 4,294,967,296 is not a planning input. |
| Choosing how many subnets to cut | Fewer and larger | Every boundary pays the same four-address toll regardless of its size. |
The one to look at today
Find your smallest primary ranges and work out what fraction of each is actually assignable. Anything at /29 or /28 is paying a double-digit percentage for the privilege of being its own subnet, and the question to ask of each is the one from #63: which of Cloud NAT, Private Google Access, VPC Flow Logs or alias ranges genuinely differs here. Where the answer is none, you are buying four reserved addresses and a name you can never change in exchange for nothing the platform acts on. You cannot merge them now — but the next environment does not have to repeat it.
Closing Thought
What I find genuinely interesting here is that two of the four reservations are archaeology. The broadcast address is held back in a network that cannot broadcast, and the second-to-last is held back for a purpose nobody has written down. Neither is a mistake. A primary subnet range has to be legible as a subnet to operating systems, DHCP clients, monitoring tools and engineers, and legibility means keeping the shape even where the platform has moved past the meaning. The cost of compatibility is paid in addresses, and it is paid per subnet, forever.
The proof is sitting next to it, which is what makes this post possible rather than speculative. Secondary ranges and IPv6 subnets are both newer, both carry no inherited convention, and both reserve either nothing or something named only for what it actually does. Six posts into addressing, that is the pattern underneath most of what has surprised me: the model is cleaner than the vocabulary, the vocabulary is kept for compatibility, and the places where it costs something real are the places where a small number meets an old convention.
#67 leaves the ranges and takes the addresses themselves: internal and external IP addresses, static and ephemeral — what each one is bound to, and what happens to it when the thing it is attached to goes away.
Comments