Subnetting is often taught as several collections of facts to memorise.
/24 means 256 addresses
/25 means 128
/26 means 64
/27 means 32
/28 means 16
Then another collection appears:
128
192
224
240
248
252
254
255
These are mask values.
A third collection follows:
128
64
32
16
8
4
2
1
These are block increments.
The numbers are related, but they are often presented as separate tables. The student is left trying to remember whether 224 belongs to /26, /27 or the part of the lesson that everyone else appeared to understand immediately.
Someone says:
172.20.44.173/20
and an experienced network engineer replies:
172.20.32.0 to 172.20.47.255
The answer can look like a parlour trick.
It is not.
The engineer recognised a small set of relationships:
- IPv4 contains 32 bits
- a prefix leaves a known number of host bits
- host bits produce powers-of-two block sizes
- each mask creates regularly spaced boundaries
- an address belongs to the block beginning at the previous valid boundary
Subnetting does not require magic numbers. It requires one model applied repeatedly.
I still keep a reference table nearby. It is useful for speed, but it is no longer the source of the answer.
The same bits produce the prefix, mask and block size
Consider a /26.
It has:
26 network bits
6 host bits
The six host bits create:
2^6 = 64 addresses
The mask is:
11111111.11111111.11111111.11000000
The final mask octet is:
11000000
which is:
128 + 64 = 192
The block increment is:
256 - 192 = 64
The three apparently independent facts are therefore:
prefix: /26
mask: 255.255.255.192
block size: 64
They all came from the same six host bits.
prefix
│
▼
host bits
│
├── address count
├── subnet mask
└── boundary increment
Remembering one value can help derive the others. Remembering none of them is survivable too.
Begin with the requirement, not the prefix
A subnet should not begin with:
I think a /24 looks sensible.
It should begin with:
How many simultaneous address consumers
must this subnet support?
Suppose a subnet needs space for:
- 70 application instances
- 10 load-balancer or service interfaces
- 20 addresses of deployment headroom
- 15 addresses for expected growth
The planning requirement is:
70 + 10 + 20 + 15 = 115 addresses
CIDR blocks have power-of-two sizes. Find the smallest power of two that is at least 115:
64 too small
128 large enough
A block of 128 addresses uses seven host bits:
2^7 = 128
IPv4 contains 32 bits, so the prefix is:
32 - 7 = 25
The resulting block is:
/25
The design process is:
REQUIRED CAPACITY
│
▼
NEXT POWER OF TWO
│
▼
HOST BITS
│
▼
PREFIX LENGTH
No /25 was memorised. It was derived from the requirement.
Round up, never down
Suppose a workload requires 300 address positions.
The nearby powers of two are:
256
512
A /24 provides 256 total addresses, so it is too small.
A /23 provides 512. It is the smallest block that satisfies the raw requirement.
required: 300
next power: 512
host bits: 9
prefix: 32 - 9
result: /23
Address exhaustion does not award partial credit.
| Required total addresses | Next power of two | Host bits | Prefix |
|---|---|---|---|
| 10 | 16 | 4 | /28 |
| 25 | 32 | 5 | /27 |
| 50 | 64 | 6 | /26 |
| 100 | 128 | 7 | /25 |
| 200 | 256 | 8 | /24 |
| 700 | 1,024 | 10 | /22 |
| 3,000 | 4,096 | 12 | /20 |
Every row follows:
smallest 2^h >= requirement
prefix = 32 - h
The total requirement must include operating headroom. Platform-specific reservations are then applied before selecting the final prefix.
Apply platform rules after the binary arithmetic
The arithmetic is platform-neutral. Cloud platforms then decide which positions may be assigned and how services consume them.
For an AWS VPC IPv4 subnet, AWS reserves the first four addresses and the final address. AWS currently supports subnet prefixes from /28 to /16, and it canonicalises a supplied subnet CIDR to the actual network boundary.
For 10.0.0.0/24, AWS reserves:
10.0.0.0as the network address10.0.0.1for the VPC router10.0.0.2for DNS-related use10.0.0.3for future use10.0.0.255as the final address
The AWS planning equation is:
required assignable addresses
+ 5 AWS reservations
<= total CIDR addresses
Suppose I need 60 assignable addresses.
A /26 contains:
64 total
64 - 5 = 59 assignable
It is one address too small.
The next larger block is:
/25 = 128 total
128 - 5 = 123 assignable
The five reservations are only the first adjustment. The estimate may also need to include:
- EC2 network interfaces
- load balancers
- NAT gateways
- interface VPC endpoints
- managed databases
- EKS nodes and Pods
- replacement resources during deployments
- failover and scaling headroom
AWS Well-Architected guidance recommends planning for multiple Availability Zones, future expansion and transient capacity. A mathematically fitting subnet can still be operationally undersized.
Count host bits instead of memorising prefixes
The useful powers of two are easy to reconstruct:
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
2^8 = 256
2^9 = 512
2^10 = 1,024
2^11 = 2,048
2^12 = 4,096
2^13 = 8,192
2^14 = 16,384
2^15 = 32,768
2^16 = 65,536
If I know the capacity, I can identify the host bits. The prefix is then:
32 - host bits
For 2,048 addresses:
2^11 = 2,048
32 - 11 = 21
prefix = /21
For 32 addresses:
2^5 = 32
32 - 5 = 27
prefix = /27
A /18 is no longer a mysterious large block:
32 - 18 = 14 host bits
2^14 = 16,384 addresses
Increasing a prefix by one halves the block size. Decreasing it by one doubles the block size.
Derive the mask from the partial octet
A prefix can end at an octet boundary:
/8 = 255.0.0.0
/16 = 255.255.0.0
/24 = 255.255.255.0
/32 = 255.255.255.255
For other prefixes, one octet contains both network and host bits. I need only derive that partial octet.
For /20, the first 16 bits consume two complete octets. Four more network bits enter the third:
11110000
Add their values:
128 + 64 + 32 + 16 = 240
The mask is:
255.255.240.0
For /27, three network bits enter the fourth octet:
11100000
128 + 64 + 32 = 224
The mask is:
255.255.255.224
The partial-octet values are running totals of binary place values:
| Network bits in partial octet | Binary | Decimal |
|---|---|---|
| 1 | 10000000 |
128 |
| 2 | 11000000 |
192 |
| 3 | 11100000 |
224 |
| 4 | 11110000 |
240 |
| 5 | 11111000 |
248 |
| 6 | 11111100 |
252 |
| 7 | 11111110 |
254 |
| 8 | 11111111 |
255 |
The values are cumulative binary addition, not magic numbers.
The increment is the remaining space in the partial octet
Once I have the partial mask value, the boundary increment is:
256 - partial mask value
For /20:
256 - 240 = 16
For /27:
256 - 224 = 32
For /22:
mask = 255.255.252.0
256 - 252 = 4
| Network bits in partial octet | Mask value | Increment |
|---|---|---|
| 1 | 128 | 128 |
| 2 | 192 | 64 |
| 3 | 224 | 32 |
| 4 | 240 | 16 |
| 5 | 248 | 8 |
| 6 | 252 | 4 |
| 7 | 254 | 2 |
| 8 | 255 | 1 |
For the partial octet:
partial mask value + increment = 256
This is why 255.255.255.192 creates boundaries every 64 addresses and 255.255.240.0 creates boundaries every 16 values in the third octet.
Find the block by rounding down
Consider:
172.20.44.173/20
The mask is:
/20 = 255.255.240.0
The interesting octet is the third. Its increment is:
256 - 240 = 16
Valid third-octet boundaries include:
0
16
32
48
64
...
240
The address has third octet 44.
The previous boundary is 32. The next boundary is 48.
Therefore:
network: 172.20.32.0/20
next network: 172.20.48.0/20
final address: 172.20.47.255
The complete range is:
172.20.32.0 - 172.20.47.255
The formal calculation is:
floor(44 / 16) × 16 = 32
The mental version is:
Which multiple of 16
comes immediately before 44?
A valid CIDR starts on its boundary
Suppose someone proposes:
10.64.22.0/22
A /22 mask is:
255.255.252.0
The third-octet increment is:
256 - 252 = 4
Valid boundaries include:
0
4
8
12
16
20
24
28
22 is not one of them. It falls inside the block beginning at 20.
The canonical network is:
10.64.20.0/22
Its range is:
10.64.20.0 - 10.64.23.255
A compact check is:
proposed octet mod increment
For 20:
20 mod 4 = 0
Aligned.
For 22:
22 mod 4 = 2
Not aligned.
The network identifier has every host bit set to zero. A proposed CIDR containing non-zero host bits identifies an address inside the block, not its canonical start.
Divide a parent block without listing every address
Suppose a fictional organisation receives:
10.64.0.0/16
I want /20 environment allocations.
The prefix difference is:
20 - 16 = 4
Four additional network bits create:
2^4 = 16 child blocks
Each /20 contains:
2^(32 - 20) = 4,096 addresses
A /20 moves in increments of 16 in the third octet:
10.64.0.0/20
10.64.16.0/20
10.64.32.0/20
10.64.48.0/20
...
10.64.240.0/20
The formula is:
number of equal children
= 2^(child prefix - parent prefix)
The formula proves there are 16 children. The increment identifies where each one begins.
Unequal requirements need VLSM
Equal-size subnetting is simple. Real systems rarely have equal requirements.
Suppose one VPC has these three-Availability-Zone requirements:
| Purpose | Subnets | Required AWS-assignable addresses per subnet |
|---|---|---|
| EKS applications | 3 | 900 |
| Public entry | 3 | 40 |
| Data services | 3 | 100 |
Add AWS’s five reservations to each subnet:
| Purpose | Calculation | Next power of two | Prefix |
|---|---|---|---|
| EKS applications | 900 + 5 = 905 |
1,024 | /22 |
| Public entry | 40 + 5 = 45 |
64 | /26 |
| Data services | 100 + 5 = 105 |
128 | /25 |
The design therefore needs:
3 × /22 application subnets
3 × /25 data subnets
3 × /26 public subnets
This is Variable Length Subnet Masking, or VLSM: unequal requirements receive different prefix lengths from the same parent allocation.
The useful principle is not the name. It is refusing to give every consumer the same box merely because equal boxes are easier to draw.
Allocate the largest blocks first
When fitting unequal subnets into a parent, allocate the largest first.
Suppose production receives the aligned parent:
10.64.128.0/18
It spans:
10.64.128.0 - 10.64.191.255
A possible allocation is:
application-a 10.64.128.0/22
application-b 10.64.132.0/22
application-c 10.64.136.0/22
data-a 10.64.140.0/25
data-b 10.64.140.128/25
data-c 10.64.141.0/25
public-a 10.64.141.128/26
public-b 10.64.141.192/26
public-c 10.64.142.0/26
A /22 moves by four in the third octet:
128
132
136
140
A /25 divides one /24 into two halves:
.0 - .127
.128 - .255
A /26 divides one /24 into four quarters:
.0 - .63
.64 - .127
.128 - .191
.192 - .255
Large-first allocation reduces the chance that small ranges will fragment the parent and leave no aligned location for a later large subnet.
Total free addresses are not contiguous free capacity
Suppose a parent allocation has 4,096 unallocated addresses in total.
Those addresses are spread across eight disconnected /23 gaps:
8 × 512 = 4,096
A new workload needs one /20:
1 × 4,096 = 4,096
The quantities match, but the allocation cannot be made. A /20 requires one contiguous, aligned block.
TOTAL FREE
4,096 addresses
ACTUAL SHAPE
/23 /23 /23 /23
/23 /23 /23 /23
REQUEST
one aligned /20
Address planning therefore needs to track:
- total remaining capacity
- the largest contiguous free block
- alignment of the free ranges
- whether related ranges can grow into adjacent space
Leaving deliberate gaps can be better than packing the first version tightly:
application-a /22
reserved-a /22
application-b /22
reserved-b /22
application-c /22
reserved-c /22
Each Availability Zone receives adjacent growth space. Planning space is consumed before resource addresses are, but future renumbering may be avoided.
Preserve architectural structure
A good address plan reveals the network architecture.
For example:
10.64.0.0/16
│
├── 10.64.0.0/18 development
├── 10.64.64.0/19 staging
├── 10.64.96.0/19 shared infrastructure
├── 10.64.128.0/18 production
└── 10.64.192.0/18 future use
Every prefix is aligned. Together, the allocations cover the /16 without overlap.
Within production:
10.64.128.0/18
│
├── Availability Zone A
├── Availability Zone B
├── Availability Zone C
└── reserved expansion
The useful hierarchy is:
ORGANISATION POOL
│
▼
REGION
│
▼
ENVIRONMENT OR VPC
│
▼
AVAILABILITY ZONE
│
▼
SUBNET PURPOSE
Amazon VPC IP Address Manager can organise address space into pools, allocate CIDRs and monitor utilisation, overlap and compliance.
IPAM can manage allocation. Architecture still decides why a particular /22 belongs in a particular place.
Summarisation is subnetting in reverse
Suppose these four prefixes have been allocated:
10.64.96.0/20
10.64.112.0/20
10.64.128.0/20
10.64.144.0/20
They are contiguous and contain:
4 × 4,096 = 16,384 addresses
That quantity corresponds to a /18.
However, a /18 advances by 64 in the third octet:
0
64
128
192
96 is not a valid /18 boundary. The four blocks cannot be represented by one /18 without including addresses outside the set.
Now consider:
10.64.128.0/20
10.64.144.0/20
10.64.160.0/20
10.64.176.0/20
These begin at 128, a valid /18 boundary, and cover:
10.64.128.0 - 10.64.191.255
They can be summarised as:
10.64.128.0/18
Size is not enough. Boundary alignment matters.
The traditional host formula has limits
The familiar formula is:
usable hosts = 2^host_bits - 2
It removes the all-zero host position used as the network identifier and the all-one position traditionally used as the directed broadcast address.
For a /26:
2^6 - 2 = 62
This remains useful for ordinary IPv4 LAN reasoning, but it is not universal.
A /31 can use both addresses on supported point-to-point links. RFC 3021 defines this special use to avoid spending four addresses on a link that needs two endpoints. A /32 identifies one address.
AWS VPC subnets use their own five-address reservation rule and support IPv4 subnet prefixes only from /28 to /16.
Keep the calculations separate:
RAW CIDR CAPACITY
2^host_bits
and:
PLATFORM-ASSIGNABLE CAPACITY
raw capacity
minus platform reservations
The binary calculation stays stable while the platform applies its operating rules.
Tools should verify the model
I still use:
- subnet calculators
- Python’s
ipaddressmodule - Terraform or OpenTofu functions
- IPAM
- cloud-platform validation
- automated overlap checks
The difference is what I expect from them.
Weak workflow:
enter address
copy answer
hope the input represented
what I intended
Stronger workflow:
estimate answer
run tool
compare result
investigate disagreement
A small Python check is:
from ipaddress import IPv4Network
network = IPv4Network("172.20.44.173/20", strict=False)
print(f"Network: {network.network_address}")
print(f"Final: {network.broadcast_address}")
print(f"Count: {network.num_addresses}")
print(f"Prefix: /{network.prefixlen}")
Expected output:
Network: 172.20.32.0
Final: 172.20.47.255
Count: 4096
Prefix: /20
strict=False accepts an address with host bits and returns its canonical network. The tool confirms the reasoning rather than replacing it.
A repeatable method
When I need to choose and place a subnet:
1. Count workload demand
Include:
- current resources
- scaling and failover
- rolling replacement
- service interfaces
- expected growth
2. Apply platform reservations
For an AWS VPC subnet:
required total
= required assignable + 5
3. Round up to the next power of two
smallest 2^h
that is not smaller
than the requirement
4. Convert host bits into a prefix
prefix = 32 - h
5. Find the mask and increment
Derive the partial mask octet from binary place values:
increment = 256 - partial mask value
6. Choose an aligned boundary
The interesting octet must be a multiple of the increment.
7. Find the range
Move forward by one increment to find the next boundary, then step back by one address to find the final position.
8. Check the architecture
Verify that the complete range:
- fits inside its parent
- does not overlap another allocation
- leaves useful contiguous growth space
- supports the required Availability Zones
9. Verify independently
Use a calculator, code, IPAM or platform validation and investigate any disagreement.
REQUIREMENT
│
▼
PLATFORM RULES
│
▼
POWER OF TWO
│
▼
HOST BITS
│
▼
PREFIX
│
▼
ALIGNED RANGE
│
▼
ARCHITECTURAL ALLOCATION
The design checklist
| Area | Question |
|---|---|
| Demand | How many assignable addresses are required? |
| Platform | Which positions does the target platform reserve? |
| Growth | What is needed during scaling, failover and replacement? |
| Size | What is the next power of two above the total requirement? |
| Boundary | Where can a block of that size begin legally? |
| Parent | Does the complete range fit inside its parent allocation? |
| Overlap | Does it intersect any allocated or reserved range? |
| Fragmentation | Does it preserve useful contiguous space? |
| Availability | Does each Availability Zone receive independent capacity? |
| Summary | Can related allocations form meaningful aggregate routes? |
| Verification | Does an independent tool produce the same result? |
These questions replace the subnetting recital with a design process.
The mental model
ADDRESS REQUIREMENT
│
▼
PLATFORM RULES
│
▼
ROUND TO POWER OF TWO
│
▼
HOST BITS
│
▼
PREFIX LENGTH
│
┌────────────┴────────────┐
│ │
▼ ▼
SUBNET MASK BLOCK SIZE
│ │
▼ ▼
INCREMENT CAPACITY
│ │
└────────────┬────────────┘
▼
ALIGNED BOUNDARY
│
▼
CIDR RANGE
│
▼
NETWORK ARCHITECTURE
The familiar mask values still exist:
192
224
240
248
252
They are not magic. They are binary network bits accumulated from left to right.
The familiar prefixes still exist:
/24
/25
/26
/27
/28
They are eight, seven, six, five and four host bits producing 256, 128, 64, 32 and 16 positions.
Subnetting becomes easier when I stop asking which number I should remember and start asking which boundary the requirement creates.
Count the consumers.
Apply the platform rules.
Round up.
Find the host bits.
Subtract from 32.
Align the range.
Check the architecture.
Then verify the answer with a tool.
The result may still be /26.
This time, it arrived with its paperwork.
References and further reading
-
RFC 4632: Classless Inter-domain Routing Defines CIDR prefix notation, IPv4 block sizes and route aggregation.
-
RFC 1878: Variable Length Subnet Table for IPv4 Provides variable-length subnet masks, decimal mask values and block sizes.
-
RFC 3021: Using 31-Bit Prefixes on IPv4 Point-to-Point Links Defines the special use of
/31prefixes for two-endpoint links. -
Amazon VPC: Subnet CIDR blocks Documents supported subnet sizes, canonical CIDRs and AWS’s five reserved IPv4 addresses.
-
AWS Well-Architected: Ensure IP subnet allocation accounts for expansion and availability Covers multi-Availability-Zone planning, future expansion and Kubernetes address consumption.
-
Amazon VPC IPAM: Plan VPC address space for subnet allocations Demonstrates dividing VPC space into CIDR pools for subnets with different requirements.
-
Amazon VPC IPAM: Monitor CIDR usage Covers utilisation, overlap and allocation monitoring.
-
Amazon VPC IPAM: Monitor CIDR usage by resource Covers resource compliance and overlap status.