A VPC owns a block of private addresses, and each subnet owns a smaller block inside it. Blocks are written in CIDR notation: a starting address, a slash, and how many bits are fixed.
An address has 32 bits. /16 fixes the first 16, so every address in the block starts with 10.0 and the other 16 bits are free: 2 to the 16th, 65,536 addresses. Each extra fixed bit halves the block, so a larger number after the slash means a smaller block.
| Block | Addresses | Use |
|---|---|---|
/16 | 65,536 | a VPC (the largest AWS allows) |
/20 | 4,096 | the default VPC's subnets |
/24 | 256, of which 251 usable | a subnet: 10.0.1.0/24 is 10.0.1.0 to 10.0.1.255 |
AWS keeps five addresses of every subnet for itself, which is why a /24 has 251 for instances.
No overlaps
Each subnet's block sits inside the VPC's block, and subnets never overlap: 10.0.1.0/24 and 10.0.2.0/24 are neighbours, while 10.0.1.0/24 and 10.0.1.128/25 share addresses and cannot both exist. Two networks that may one day be joined must not overlap either.
| Also worth knowing | |
|---|---|
| private ranges, never routed on the internet | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
| choosing a size | pick a VPC block bigger than you think you need; it is hard to change later |
aws ec2 describe-subnets --query "Subnets[].[AvailabilityZone,CidrBlock,AvailableIpAddressCount]" --output tableThis lists the default VPC's three /20 subnets, each with 4,091 addresses free: 4,096 minus the five.