I can enter an IPv4 address and prefix into a subnet calculator.
It will immediately tell me:
- the subnet mask
- the network address
- the final address
- the traditional host range
- the number of addresses
That is useful.
It is also easy to mistake the output for understanding.
Input:
192.0.2.130/26
Output:
Network: 192.0.2.128
Final: 192.0.2.191
Host range: 192.0.2.129 - 192.0.2.190
Mask: 255.255.255.192
The calculator has answered the immediate question.
It has not explained why the network begins at .128, why the block ends at .191, or why the next block begins at .192.
Without that model, CIDR becomes a collection of remembered fragments:
/24 means 256 addresses
/26 means 64 addresses
/28 means 16 addresses
That works until I meet:
10.42.77.19/20
or need to divide:
10.64.0.0/16
across environments, Availability Zones and subnet purposes.
Then the memorised table starts shedding screws.
The underlying model is much smaller than the collection of shortcuts.
An IPv4 address is a 32-bit value.
A prefix length says how many leading bits remain fixed as the network boundary.
The remaining bits vary through positions inside that block.
Subnetting is not primarily decimal arithmetic. It is binary boundary management displayed in decimal clothing.
Once the binary structure is visible, the decimal ranges stop looking arbitrary.
IPv4 is one 32-bit value
An IPv4 address contains 32 binary digits.
Each digit is either:
0
or:
1
The bits are normally displayed as four groups of eight.
Each group is an octet.
8 bits 8 bits 8 bits 8 bits
xxxxxxxx . xxxxxxxx . xxxxxxxx . xxxxxxxx
The familiar address:
192.0.2.130
is the dotted-decimal display of:
11000000.00000000.00000010.10000010
The dots improve readability.
They are not extra information carried in the address.
A 32-bit address space contains:
2^32 = 4,294,967,296
possible bit patterns.
Not every pattern is available as an ordinary public host address. Some blocks are private, loopback, link-local, multicast, documentation or otherwise special purpose.
For the arithmetic, the starting point is:
IPv4 address = 32 bits
Each octet ranges from 0 to 255
An octet has eight bit positions.
place value: 128 64 32 16 8 4 2 1
These are powers of two:
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
A 1 contributes its place value.
A 0 contributes nothing.
11000000
128 + 64 = 192
10000010
128 + 2 = 130
Therefore:
192 = 11000000
0 = 00000000
2 = 00000010
130 = 10000010
The largest octet is:
11111111
128 + 64 + 32 + 16 + 8 + 4 + 2 + 1
= 255
The smallest is:
00000000 = 0
That is why each dotted-decimal component ranges from 0 to 255.
It is not an IPv4 convention selected from a hat.
It is the complete numeric range of eight bits.
Converting decimal to binary
To convert a decimal octet, subtract the largest place value that fits and continue to the right.
Convert:
172
172 - 128 = 44
64 does not fit
44 - 32 = 12
16 does not fit
12 - 8 = 4
4 - 4 = 0
Lay the result over the positions:
place value: 128 64 32 16 8 4 2 1
bit: 1 0 1 0 1 1 0 0
Therefore:
172 = 10101100
For 19:
16 + 2 + 1 = 19
19 = 00010011
The leading zeros matter.
An octet is always eight bits:
2 = 00000010
The fixed width preserves its position inside the complete address.
The prefix draws the boundary
An address by itself does not identify its surrounding network.
10.42.77.19
could belong to:
10.0.0.0/8
10.42.0.0/16
10.42.64.0/18
10.42.77.0/24
10.42.77.16/28
The address has not changed.
The boundary has.
A prefix length says how many of the 32 leading bits describe the network.
network bits + variable bits = 32
For /24:
24 fixed network bits
8 variable bits
For /20:
20 fixed network bits
12 variable bits
For /28:
28 fixed network bits
4 variable bits
The variable bits identify every position inside the block.
This is the central arithmetic of CIDR.
The mask is the boundary written as bits
A subnet mask is another 32-bit value.
Network bits are 1.
Variable bits are 0.
For /24:
11111111.11111111.11111111.00000000
255.255.255.0
For /16:
11111111.11111111.00000000.00000000
255.255.0.0
For /26:
11111111.11111111.11111111.11000000
The final mask octet is:
128 + 64 = 192
Therefore:
/26 = 255.255.255.192
A normal CIDR mask contains one uninterrupted run of 1 bits followed by one uninterrupted run of 0 bits.
valid:
11111111.11111111.11110000.00000000
not a CIDR prefix mask:
11111111.11101111.11110000.00000000
The prefix length is simply the number of leading 1 bits.
255.255.240.0
11111111.11111111.11110000.00000000
Count them:
8 + 8 + 4 = 20
Therefore:
255.255.240.0 = /20
CIDR notation compresses the mask into one number.
CIDR replaced fixed class boundaries
Early IPv4 addressing used fixed classes.
The familiar historical associations were approximately:
Class A /8
Class B /16
Class C /24
Those fixed sizes allocated address space in coarse chunks.
Classless Inter-Domain Routing allowed prefixes to be allocated and advertised at arbitrary bit boundaries. It improved address allocation and supported route aggregation.
Today:
10.20.0.0/17
is simply a /17 block.
Calling it a partial Class B network adds no useful architectural information.
Classful terminology still appears in old documentation and shorthand.
It should not be the basis of a new address plan.
The prefix is the boundary.
Prefix length determines raw block capacity
For prefix length p:
variable bits = 32 - p
The number of positions in the block is:
2^(32 - p)
For /24:
2^8 = 256
For /26:
2^6 = 64
For /20:
2^12 = 4,096
Increasing the prefix by one fixes one more bit.
The block halves.
/24 = 256
/25 = 128
/26 = 64
/27 = 32
/28 = 16
/29 = 8
/30 = 4
/31 = 2
/32 = 1
Decreasing the prefix by one doubles the block.
/24 = 256
/23 = 512
/22 = 1,024
/21 = 2,048
/20 = 4,096
A useful table is:
| Prefix | Mask | Raw positions |
|---|---|---|
/16 |
255.255.0.0 |
65,536 |
/20 |
255.255.240.0 |
4,096 |
/22 |
255.255.252.0 |
1,024 |
/24 |
255.255.255.0 |
256 |
/25 |
255.255.255.128 |
128 |
/26 |
255.255.255.192 |
64 |
/27 |
255.255.255.224 |
32 |
/28 |
255.255.255.240 |
16 |
/29 |
255.255.255.248 |
8 |
/30 |
255.255.255.252 |
4 |
/31 |
255.255.255.254 |
2 |
/32 |
255.255.255.255 |
1 |
The table is useful once the formula underneath it is understood.
Read one complete CIDR block
Consider:
192.0.2.130/26
The first three octets are entirely inside the fixed prefix.
The interesting work occurs in the final octet.
address:
130 = 10000010
mask:
192 = 11000000
Apply binary AND:
10000010
11000000
--------
10000000
10000000 = 128
The canonical network is:
192.0.2.128/26
The mask preserved the fixed bits and set every variable bit to zero.
Find the final address
A /26 has six variable bits.
The final position uses every variable bit as 1.
network bits | variable bits
10 | 111111
The final octet is:
10111111 = 191
Therefore the raw mathematical block is:
192.0.2.128 - 192.0.2.191
The all-zero variable pattern identifies the first aligned position.
The all-one pattern identifies the final position.
What those positions mean depends on the link and platform.
MATHEMATICAL CIDR BLOCK
192.0.2.128 - 192.0.2.191
64 positions
TRADITIONAL MULTI-ACCESS SUBNET
network: 192.0.2.128
broadcast: 192.0.2.191
hosts: 192.0.2.129 - 192.0.2.190
ORDINARY AWS VPC SUBNET MODEL
first four and final positions reserved
broadcast delivery not supported
The example uses a documentation block, not a proposed AWS subnet. The comparison shows why mathematical capacity and platform capacity must not be confused.
The final address has platform-specific meaning
The all-one variable pattern always identifies the final position in the block.
Its operational meaning varies.
TRADITIONAL LAN
final position is the
directed broadcast address
/31 POINT-TO-POINT LINK
both positions may identify
the two endpoints
/32
the network and final position
are the same address
AWS VPC SUBNET
broadcast delivery is unsupported
and the final position is reserved
Traditional host arithmetic often uses:
2^variable_bits - 2
For /26:
64 - 2 = 62
That is useful for conventional multi-access subnetting.
It is not a universal law for every prefix and platform.
The CIDR prefix range runs from /0 to /32. RFC 3021 separately defines the point-to-point use of /31, where both addresses may represent endpoints.
Use the faster block-increment method
Binary AND explains why the boundary exists.
The block increment is often faster in daily work.
A /26 mask is:
255.255.255.192
The partial mask octet is 192.
increment = 256 - 192 = 64
The boundaries in that octet are:
0
64
128
192
The value 130 lies between 128 and 192.
Therefore:
network: 192.0.2.128
next block: 192.0.2.192
final: 192.0.2.191
The method is:
increment = 256 - partial mask octet
Then find the largest boundary not greater than the address value.
Octet-aligned prefixes need no partial-octet calculation
Prefixes divisible by eight contain no partial mask octet.
For:
10.42.77.19/16
retain the two complete network octets:
10.42
Set every following octet to zero:
10.42.0.0/16
The general branch is:
IS PREFIX A MULTIPLE OF EIGHT?
yes
│
▼
retain complete network octets
set remaining octets to zero
no
│
▼
find partial mask octet
calculate increment
find preceding boundary
For /0, no address bits are fixed and the block is 0.0.0.0/0.
For /32, every bit is fixed and the network and final position are the supplied address.
Non-octet prefixes are where the model earns its keep
Consider:
10.42.77.19/20
The mask is:
11111111.11111111.11110000.00000000
255.255.240.0
The partial octet is the third.
increment = 256 - 240 = 16
The boundaries are:
0
16
32
48
64
80
96
112
128
144
160
176
192
208
224
240
The address has third octet:
77
It lies between:
64 and 80
Therefore:
network: 10.42.64.0/20
next block: 10.42.80.0/20
final: 10.42.79.255
The block contains:
2^(32 - 20)
= 2^12
= 4,096 positions
Binary AND reaches the same result.
77:
01001101
mask octet:
11110000
AND:
01001101
11110000
--------
01000000 = 64
The /20 is no longer a memorised number.
It is a visible binary division.
Subnetting increases the prefix length
Suppose an organisation receives:
10.64.0.0/16
The block contains:
2^16 = 65,536 positions
Divide it into /20 child blocks.
PARENT PREFIX
16 fixed bits
16 variable bits
CHILD PREFIX
20 fixed bits
12 variable bits
PROMOTED INTO CHILD PREFIX
4 bits
This is sometimes described as borrowing four host bits.
In classless terms, four of the parent block’s variable bits become fixed child-prefix bits.
The number of child blocks is:
2^(20 - 16)
= 2^4
= 16
The blocks are:
10.64.0.0/20
10.64.16.0/20
10.64.32.0/20
10.64.48.0/20
10.64.64.0/20
10.64.80.0/20
10.64.96.0/20
10.64.112.0/20
10.64.128.0/20
10.64.144.0/20
10.64.160.0/20
10.64.176.0/20
10.64.192.0/20
10.64.208.0/20
10.64.224.0/20
10.64.240.0/20
Subnetting does not create addresses.
It divides one existing block into more boundaries.
VLSM avoids equal boxes for unequal needs
Not every network needs the same capacity.
A platform may require:
- large EKS application subnets
- smaller ingress subnets
- data subnets
- interface-endpoint capacity
- central network services
- reserved growth space
Variable Length Subnet Masking allows differently sized child blocks to coexist inside one parent.
10.64.0.0/16
│
├── 10.64.0.0/18
├── 10.64.64.0/20
├── 10.64.80.0/22
├── 10.64.84.0/24
└── remaining space reserved
A practical allocation sequence is:
- estimate the largest requirement
- choose the smallest prefix with safe headroom
- place it on a valid boundary
- continue with the next-largest requirement
- preserve contiguous space for growth
If a tier needs approximately 700 positions:
/23 = 512
is too small.
/22 = 1,024
may fit.
The platform still needs headroom for service behaviour.
EKS Pods, load balancers, endpoints and managed services all consume addresses.
CIDR arithmetic gives the capacity.
Architecture decides the margin.
Alignment is mandatory
A block must begin on a boundary appropriate to its size.
A /22 has mask:
255.255.252.0
The third-octet increment is:
256 - 252 = 4
Valid third-octet boundaries include:
0
4
8
12
16
20
...
252
This is canonical:
10.64.20.0/22
because:
20 mod 4 = 0
This is not a canonical /22 network:
10.64.22.0/22
It belongs to:
10.64.20.0/22
because:
22 mod 4 = 2
The block spans:
10.64.20.0 - 10.64.23.255
When a VPC or subnet is created through the AWS API or CLI, AWS canonicalises a non-canonical CIDR to the actual network boundary.
Canonicalisation does not make an invalid plan safe.
If the canonical block overlaps an existing subnet, creation fails.
Aggregation reverses the direction
Subnetting divides a larger prefix.
Aggregation represents contiguous smaller prefixes with one larger summary.
Consider:
10.64.0.0/20
10.64.16.0/20
10.64.32.0/20
10.64.48.0/20
Together they cover:
10.64.0.0 - 10.64.63.255
They can be summarised as:
10.64.0.0/18
Four /20 blocks contain:
4 × 4,096 = 16,384 positions
A /18 also contains:
2^14 = 16,384 positions
The child blocks are contiguous, aligned and share the same leading 18 bits.
Aggregation works when allocations are:
- contiguous
- correctly aligned
- exactly covered by the summary
- intended to receive the same routing treatment
These blocks:
10.64.0.0/20
10.64.32.0/20
cannot safely be advertised as:
10.64.0.0/18
without also claiming the missing ranges.
A summary route that includes addresses owned elsewhere is not simplification.
It is an attractive lie in a routing table.
Private space is still real address space
RFC 1918 reserves:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
The middle range is often misremembered as every 172.x.x.x address.
A /12 mask is:
255.240.0.0
The second-octet increment is:
256 - 240 = 16
The block begins at 16 and stops before the next boundary at 32.
Therefore the private range is:
172.16.0.0 - 172.31.255.255
These are not inside it:
172.15.10.20
172.32.10.20
Private addresses are reusable.
That creates overlap risk when independently designed networks later connect.
Private does not mean planning-free.
It means the address is not globally unique.
Special-purpose ranges are not spare capacity
Non-public-looking space is not automatically available for internal assignment.
Special-purpose examples include:
- loopback
- link-local
- multicast
- shared address space
- documentation ranges
- protocol reservations
IANA maintains the authoritative IPv4 Special-Purpose Address Registry, including whether each block is valid as a source or destination, forwardable or globally reachable.
For documentation, use:
192.0.2.0/24
198.51.100.0/24
203.0.113.0/24
An address that does not currently respond to a ping has not volunteered for architecture duty.
Apply the model to AWS VPC subnets
AWS permits standard IPv4 VPC subnet sizes from /16 through /28.
For an ordinary AWS VPC subnet, the first four positions and final position are reserved.
10.0.0.0 network position
10.0.0.1 VPC router
10.0.0.2 DNS-related reservation
10.0.0.3 future use
10.0.0.255 final position
AWS does not support broadcast delivery inside a VPC, but it reserves the final address.
The ordinary calculation is:
addresses available for assignment
to customer resources
= raw positions - 5
| Prefix | Raw positions | Standard AWS-assignable positions |
|---|---|---|
/24 |
256 | 251 |
/26 |
64 | 59 |
/28 |
16 | 11 |
This is a platform rule, not a mathematical property of CIDR.
AWS documents a BYOIP exception in which all addresses in the brought range, including the first and final positions, may be usable.
Subnet CIDR reservations can reduce automatic assignment further, and existing resources may retain addresses even while stopped.
The useful capacity model is:
RAW CIDR POSITIONS
2^(32 - prefix)
│
▼
PLATFORM RESERVATIONS
standard AWS reservation model
│
▼
SERVICE CONSUMPTION
network interfaces
load balancers
NAT gateways
endpoints
EKS nodes and Pods
managed services
│
▼
OPERATIONAL HEADROOM
The binary block size is raw capacity.
The platform and architecture determine how much remains useful.
AWS subnet boundaries are durable
An IPv4 subnet CIDR cannot be changed after the subnet is created.
Changing the boundary requires a replacement subnet and workload migration.
CIDR MATHEMATICS
determines capacity
SERVICE CONSUMPTION
determines headroom
SUBNET IMMUTABILITY
determines the cost
of getting it wrong
Leave growth space around important allocations rather than assuming a live subnet can later be enlarged in place.
A corrected bfstore allocation
Suppose bfstore reserves:
10.64.0.0/16
This is an educational plan rather than a final approved allocation.
A valid top-level division is:
| Allocation | Prefix | Range | Raw positions |
|---|---|---|---|
| Development | 10.64.0.0/18 |
10.64.0.0–10.64.63.255 |
16,384 |
| Staging | 10.64.64.0/19 |
10.64.64.0–10.64.95.255 |
8,192 |
| Shared infrastructure | 10.64.96.0/19 |
10.64.96.0–10.64.127.255 |
8,192 |
| Production | 10.64.128.0/18 |
10.64.128.0–10.64.191.255 |
16,384 |
| Reserved | 10.64.192.0/18 |
10.64.192.0–10.64.255.255 |
16,384 |
| Total | 65,536 |
Every child is aligned.
The allocations are contiguous and non-overlapping.
A previous proposal such as:
10.64.96.0/18
would not be a valid /18 boundary. It canonicalises to:
10.64.64.0/18
which would overlap the staging range.
The corrected production block begins at the next valid /18 boundary:
10.64.128.0/18
Describe the allocation as a contract
allocation:
name: bfstore-development
cidr: 10.64.0.0/18
owner: platform-networking
capacity:
raw_positions: 16384
aws_reserved_per_standard_subnet: 5
structure:
availability_zones: 3
subnet_classes:
- ingress
- application
- data
- endpoints
growth:
contiguous_space_required: true
review_trigger: 60_percent_allocated
routing:
summary: 10.64.0.0/18
overlap:
checked_against:
- production
- corporate-network
- partner-networks
- disaster-recovery
Development can then divide its /18 by Availability Zone and subnet purpose.
10.64.0.0/18
│
├── Availability Zone A
│ ├── ingress
│ ├── application
│ ├── data
│ └── endpoints
│
├── Availability Zone B
│ ├── ingress
│ ├── application
│ ├── data
│ └── endpoints
│
└── Availability Zone C
├── ingress
├── application
├── data
└── endpoints
Application subnets serving EKS may need more space than ingress or data subnets.
Endpoint density may justify a separate class.
The plan should preserve summaries and contiguous growth where possible.
A CIDR block is not only capacity.
It is an ownership, routing, growth and failure boundary.
A general CIDR-reading procedure
Given:
address/prefix
use this process.
1. Count the variable bits
variable bits = 32 - prefix
2. Calculate raw positions
positions = 2^variable_bits
3. Write the mask
Use one 1 for each prefix bit and one 0 for each variable bit.
Convert each octet to decimal.
4. Check whether the prefix is octet-aligned
If the prefix is divisible by eight:
- retain the complete network octets
- set every following octet to zero
- skip the partial-octet increment
Otherwise, continue with the partial mask octet.
5. Calculate the increment
increment = 256 - partial mask octet
6. Find the preceding boundary
Find the largest multiple of the increment not greater than the address value in that octet.
7. Construct the canonical network
Set every variable bit to zero.
8. Find the final position
Set every variable bit to one.
For the ordinary partial-octet method, this is also one address before the next block.
9. Apply edge semantics
/0
complete IPv4 space
/31
two-position point-to-point use
where supported
/32
one exact address
10. Apply platform rules
Determine:
- traditional broadcast semantics
- AWS or other provider reservations
- BYOIP or platform exceptions
- subnet CIDR reservations
- service-specific address consumption
- boundary immutability
The arithmetic finds the block.
The platform determines how it may be used.
Questions I now ask
Representation
What is the complete
32-bit value?
Prefix
How many leading bits
remain fixed?
Capacity
How many positions
exist in the block?
Boundary
Where does the canonical
network begin?
Final position
Where does the aligned
block end?
Semantics
What do the first and final
positions mean on this platform?
Reservations
How many positions may
resources actually receive?
Alignment
Does the proposed child block
begin on a valid boundary?
Subdivision
How many child prefixes
fit inside the parent?
Aggregation
Can the children be summarised
without claiming another range?
Overlap
Will this allocation conflict
with a connected network?
Growth
Has contiguous space been left
for future expansion?
These questions turn an address into an architectural object.
The mental model I am keeping
My earlier model was:
192.0.2.130/26
four decimal numbers
plus a subnetting suffix
The stronger model is:
IPv4 ADDRESS
│
▼
32 BITS
│
┌───────────┴───────────┐
│ │
▼ ▼
FIXED PREFIX VARIABLE BITS
│ │
▼ ▼
CANONICAL NETWORK RAW CAPACITY
│ │
└───────────┬───────────┘
▼
ALIGNED RANGE
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
SUBDIVISION AGGREGATION PLATFORM RULES
│ │ │
└───────────┼───────────┘
▼
NETWORK ARCHITECTURE
Binary answers:
Which numeric value does
each bit pattern represent?
The prefix answers:
How many leading bits
remain fixed?
The network address answers:
What is the first position
in this aligned block?
The final address answers:
Where does the block stop
before the next one begins?
Subnetting answers:
How does a larger allocation
become smaller boundaries?
Aggregation answers:
How can related boundaries
be represented by one route?
Platform rules answer:
What do the positions mean,
and how many may be assigned?
CIDR notation is compact because the underlying idea is compact.
address/prefix
The address supplies 32 bits.
The prefix tells us where to draw the line.
To understand an IPv4 block, keep the leading prefix bits fixed and allow the remaining bits to vary through every possible combination.
The all-zero variable pattern gives the canonical network.
The all-one pattern gives the final position.
The number of variable bits gives the raw capacity.
Increasing the prefix creates more, smaller child blocks.
Decreasing it creates fewer, larger blocks.
That is subnetting.
The calculators remain useful.
I will continue using them.
But now they check the arithmetic rather than supply the model.
The /20 is no longer punctuation.
It is twenty fixed bits, twelve changing bits and 4,096 positions waiting to be designed carefully.
References and further reading
- RFC 4632: Classless Inter-Domain Routing
- RFC 950: Internet Standard Subnetting Procedure
- RFC 1878: Variable Length Subnet Table for IPv4
- RFC 1918: Address Allocation for Private Internets
- RFC 3021: Using 31-Bit Prefixes on IPv4 Point-to-Point Links
- RFC 5737: IPv4 Address Blocks Reserved for Documentation
- IANA IPv4 Special-Purpose Address Registry
- Amazon VPC: Subnet CIDR blocks
- Amazon EC2 API: CreateSubnet
- AWS Well-Architected: Plan subnet allocation for expansion