A /20 has the netmask 255.255.240.0 and holds 4,096 addresses, 4,094 of them usable hosts. It covers 16 consecutive values of the third octet: 172.31.0.0/20 runs from 172.31.0.0 to 172.31.15.255, the same span as 16 /24s side by side.
The numbers
Network 172.31.0.0/20
Broadcast 172.31.15.255
Netmask 255.255.240.0
Wildcard 0.0.15.255
First host 172.31.0.1
Last host 172.31.15.254
Only the first and last addresses are reserved, so 172.31.1.0, 172.31.1.255 and 172.31.15.0 are ordinary hosts here.
How it fits
A /16 holds 16 /20s and a /19 holds two. A /20 splits into 2 /21s, 4 /22s or 16 /24s; the tool below lists the /24s. The boundaries fall on multiples of 16 in the third octet: .0, .16, .32 … .240.
Where you’ll see it
- AWS default subnets. Every region’s default VPC is
172.31.0.0/16, with one /20 default subnet per availability zone:172.31.0.0/20,172.31.16.0/20,172.31.32.0/20and so on. AWS reserves 5 addresses in each, leaving 4,091. - Your own VPC layouts. A /16 cut into /20s gives 16 subnets of about 4,000 hosts: enough for public, private and data tiers in three zones, with seven left for later.
- Docker. Once Docker’s default pools have used
172.17.0.0/16through172.31.0.0/16, it hands out /20s from192.168.0.0/16:192.168.0.0/20,192.168.16.0/20and on. Those can land on top of a home or office LAN.
Gotchas
- A /20 starts on a multiple of 16.
172.31.8.0/20has host bits set: the tool reads it as172.31.0.0/20, and stricter parsers, such as Python’sipaddress, reject it. If you meant a block that starts at172.31.8.0, the largest one that does is172.31.8.0/21, which runs to172.31.15.255. - Docker on a 192.168 LAN. If
docker network inspectshows Compose networks in192.168.x.0/20, setdefault-address-poolsin/etc/docker/daemon.jsonto a range your LANs and VPNs don’t use, then recreate the networks.
In your stack
# Terraform: one /20 per availability zone
[for i in range(3) : cidrsubnet("172.31.0.0/16", 4, i)]
# ["172.31.0.0/20", "172.31.16.0/20", "172.31.32.0/20"]
cidrnetmask("172.31.0.0/20") # "255.255.240.0"
import ipaddress
zone = ipaddress.ip_network("172.31.0.0/20")
len(list(zone.subnets(new_prefix=24))) # 16
aws ec2 create-subnet --vpc-id vpc-0123456789abcdef0 --cidr-block 172.31.48.0/20 --availability-zone us-east-1d