Subnet CIDR planning and IP allocation
coreintermediateA subnet's CIDR size decides how many IP addresses it holds — but AWS reserves 5 addresses in every subnet, so a /28 (16 addresses) really only has 11 usable, not 16.
Think of it as
An apartment building with a fixed number of units, where the landlord permanently keeps 5 units for utilities and management no matter how large the building is — a bigger building just means more units left over for tenants.
What we're doing: Compute how many usable addresses a planned subnet actually has, accounting for the 5 AWS reserves.
- 1
- The -5 applies uniformly regardless of subnet size — it is a fixed AWS reservation, not a percentage.
- 3
- A /28 with only 16 total addresses loses nearly a third of its space to reserved addresses — the smaller the subnet, the bigger that proportion.
Why this works: Planning a subnet by total CIDR size alone (rather than usable IPs) is the single most common way teams run out of address space earlier than expected — 5 reserved addresses is a bigger bite out of a small subnet than a large one.
Sizing a subnet for exactly the current instance count
Wrong
Better
What you see: An Auto Scaling Group fails to launch a replacement instance during a rolling deployment because the subnet has run out of free IP addresses.
Why: A subnet sized to exactly today's count leaves no room for rolling deployments (which briefly run old and new instances together), Auto Scaling bursts, or future growth — all of which need spare addresses, not just enough for a static snapshot of today.
- Whole: def usable_ips(prefix_len): total = 2 ** (32 - prefix_len) return total - 5 # AWS reserves 5 addresses in every subnet print(usable_ips(28)) # 11
- 2 ** (32 - prefix_len) — total addresses: /28 → 16 total addresses in the block
- total - 5 — usable = total − 5: network, router, DNS, future-use, and broadcast are always reserved
Common subnet sizes and their usable IP count (5 always reserved)
Together
Remember: Every AWS subnet reserves exactly 5 addresses — usable count is 2^(32 − prefix) − 5, not the raw block size, and smaller subnets lose a proportionally bigger share to that reservation.
See also: non overlapping cidr design · route tables and egress paths

