Planning VPC address space you will not regret

Subnetting is easy arithmetic and hard planning. How to size a VPC, why AWS takes five addresses per subnet, and the allocation habits that keep the next environment from needing a migration.

· 8 min read

The arithmetic of subnetting takes a minute to learn and a calculator to do quickly. The planning is the hard part, because address space is the one decision in a VPC that is genuinely expensive to change later: you cannot resize a subnet, only replace it, and replacing it means recreating everything in it.

Start much larger than you need

Take a /16 for the VPC unless you have a reason not to. That is 65,536 addresses, which sounds absurd for a service with six instances — and costs nothing. Private address space is free; a re-addressing project is not.

Then divide it with room to spare. A common shape for a three-availability-zone region:

10.20.0.0/16          the VPC
  10.20.0.0/20        public subnets    (three /22s, one per AZ)
  10.20.16.0/20       private subnets   (three /22s, one per AZ)
  10.20.32.0/20       data subnets      (three /22s, one per AZ)
  10.20.48.0/16 …     unallocated — deliberately

Roughly half the range stays unallocated. That is not waste, it is the space the next tier, the next AZ or the next environment will need.

Why AWS gives you five fewer addresses

Every subnet loses its first address (the network address) and its last (the broadcast address) — that is IP, not AWS. AWS then reserves three more: the VPC router, the Amazon DNS resolver, and one kept for future use. So:

  • a /24 has 256 addresses, 254 usable normally, 251 on AWS;
  • a /28 — the smallest subnet AWS allows — has 16, and just 11 usable.

This bites hardest with Fargate tasks or EKS pods using the VPC CNI, where every task or pod takes a real subnet address. A /28 that looks adequate for eleven tasks has no room for a rolling deployment, which needs headroom for the new tasks while the old ones drain. The subnet calculator has an AWS mode that accounts for the five.

Leave room between allocations

Allocate on boundaries you can extend into. If your first private subnet is 10.20.16.0/22, the next contiguous /22 is free for a fourth AZ. If instead you pack subnets adjacently by exact current need, the next change has to go somewhere unrelated and your address plan stops being readable — which is how you end up with a spreadsheet nobody trusts.

Never overlap, even with things you do not peer to yet

Two VPCs with overlapping CIDRs cannot be peered, cannot both be reached over the same Transit Gateway, and cannot both be routed to from an on-premises network. The overlap is usually discovered years later, by which point one side has to be re-addressed.

The habit that prevents it: keep one register of every allocated block — including the ranges your offices, VPN clients and Kubernetes services use — and check a new block against it before creating anything. The CIDR calculator's overlap checker takes a list and reports every conflicting pair.

Two ranges deserve particular care. Docker's default bridge is 172.17.0.0/16, which collides with an RFC 1918 allocation people reach for often. And 100.64.0.0/10 — carrier-grade NAT space — is a useful pressure valve for EKS secondary CIDRs precisely because it is not RFC 1918, so it rarely clashes with anything on-premises.

A checklist before you apply

  1. Does the new block overlap anything in the register, including VPN and Kubernetes service ranges?
  2. Do the subnets have room for a rolling deployment at peak, with AWS's five reserved addresses subtracted?
  3. Is there contiguous free space next to each tier for another AZ?
  4. Is the VPC big enough that the next environment fits the same pattern?

Tools mentioned in this guide

Esc

Loading the catalog…