Quick Start: Subnetting in 5 Minutes
Six months of configuring VLANs on production switches — and debugging routing issues at 2 AM — taught me one thing clearly: subnetting is what separates “I know networking” from “I actually understand networking.” It took me embarrassingly long to get comfortable with it. Once I did, I realized I’d been overthinking it the whole time.
Here’s the core idea: an IPv4 address like 192.168.1.0/24 has two parts — the network portion and the host portion. The /24 (CIDR notation) means 24 bits are reserved for the network, leaving 8 bits for hosts.
The formula you need right now:
Usable hosts = 2^(32 - prefix_length) - 2
Examples:
/24 → 2^8 - 2 = 254 hosts
/25 → 2^7 - 2 = 126 hosts
/26 → 2^6 - 2 = 62 hosts
/27 → 2^5 - 2 = 30 hosts
/28 → 2^4 - 2 = 14 hosts
/30 → 2^2 - 2 = 2 hosts ← point-to-point WAN links
The “-2” accounts for the network address (first IP) and broadcast address (last IP). Neither can be assigned to a host.
Deep Dive: The Binary Math Behind Subnetting
You don’t need to love binary. But you do need enough fluency to work through a subnet calculation on a whiteboard during an interview — or while someone’s screaming that production is down.
How Subnet Masks Work
A subnet mask is 32 bits: consecutive 1s followed by consecutive 0s. The 1-bits identify the network. The 0-bits identify hosts within that network.
/24 mask in binary:
11111111.11111111.11111111.00000000 = 255.255.255.0
/26 mask in binary:
11111111.11111111.11111111.11000000 = 255.255.255.192
Calculating Network Address, Broadcast, and Usable Range
Let’s walk through 192.168.10.50/26 step by step.
Step 1 — Convert to binary:
IP: 192.168.10.50 = 11000000.10101000.00001010.00110010
Mask: /26 = 11111111.11111111.11111111.11000000
Step 2 — Network address (bitwise AND):
11000000.10101000.00001010.00110010
AND
11111111.11111111.11111111.11000000
= 11000000.10101000.00001010.00000000
= 192.168.10.0
Step 3 — Broadcast address (set all host bits to 1):
11000000.10101000.00001010.00111111
= 192.168.10.63
Step 4 — Usable range: 192.168.10.1 to 192.168.10.62 — 62 usable host addresses.
Python’s built-in ipaddress module verifies this instantly:
import ipaddress
network = ipaddress.ip_network('192.168.10.50/26', strict=False)
print(f"Network: {network.network_address}")
print(f"Broadcast: {network.broadcast_address}")
print(f"Usable: {network.num_addresses - 2}")
print(f"First: {list(network.hosts())[0]}")
print(f"Last: {list(network.hosts())[-1]}")
Output:
Network: 192.168.10.0
Broadcast: 192.168.10.63
Usable: 62
First: 192.168.10.1
Last: 192.168.10.62
On Linux, ipcalc handles the same thing from the terminal:
ipcalc 192.168.10.50/26
Advanced Usage: VLSM and Real-World Subnet Design
VLSM (Variable Length Subnet Masking) is where subnetting stops being theoretical. Instead of equal-sized chunks, you size each subnet for its actual workload. I’ve seen a single /24 carved into a dozen VLANs at a 40-person office — without VLSM, over 100 addresses would’ve been permanently stranded in oversized blocks nobody asked for.
VLSM: A Practical Scenario
You have 192.168.1.0/24 and need to allocate subnets for four departments:
- Sales: 100 hosts
- IT: 50 hosts
- Management: 10 hosts
- WAN link: 2 hosts
Always allocate the largest subnet first to avoid fragmentation:
Sales (100 hosts):
Need: 2^7 = 128 addresses → /25
Subnet: 192.168.1.0/25
Range: 192.168.1.1 – 192.168.1.126
Broadcast: 192.168.1.127
IT (50 hosts):
Need: 2^6 = 64 addresses → /26
Subnet: 192.168.1.128/26
Range: 192.168.1.129 – 192.168.1.190
Broadcast: 192.168.1.191
Management (10 hosts):
Need: 2^4 = 16 addresses → /28
Subnet: 192.168.1.192/28
Range: 192.168.1.193 – 192.168.1.206
Broadcast: 192.168.1.207
WAN link (2 hosts):
Need: 2^2 = 4 addresses → /30
Subnet: 192.168.1.208/30
Range: 192.168.1.209 – 192.168.1.210
Broadcast: 192.168.1.211
Total: 128 + 64 + 16 + 4 = 212 addresses used out of 256. Tight and efficient.
Subnetting a /24 Into Equal Blocks
Sometimes equal subnets are exactly what you need. Borrowing bits from the host portion doubles the subnet count each time you add a bit:
# Split 10.0.0.0/24 into 4 equal /26 subnets
# Borrow 2 bits from host portion (2^2 = 4 subnets)
python3 -c "
import ipaddress
net = ipaddress.ip_network('10.0.0.0/24')
for subnet in net.subnets(new_prefix=26):
print(subnet)
"
Output:
10.0.0.0/26
10.0.0.64/26
10.0.0.128/26
10.0.0.192/26
Hard-Won Lessons From Production Networks
Things that don’t make it into the textbooks:
- Use /30 for point-to-point WAN links, not /31 — unless you’ve confirmed both ends support RFC 3021. Many older devices silently drop /31 traffic.
- Verify before pushing to production. Run
ipcalcor the Python snippet above before touching any router or firewall config. One transposed digit in a subnet mask has cost me three hours of debugging. - Align subnets to natural boundaries. VLAN 10 maps cleanly to
10.0.10.0/24, VLAN 20 to10.0.20.0/24. Pattern-based addressing makes troubleshooting at 2 AM dramatically less painful. - Document your allocations. NetBox and phpIPAM are purpose-built for this. A spreadsheet works too. Whatever you choose, write it down — an IP conflict from an undocumented subnet can eat a full day to untangle.
- Memorize /24 through /30. In practice, around 95% of subnetting tasks fall in this range. Everything else you can calculate on the fly.
Quick reference cheat sheet:
Prefix | Mask | Addresses | Usable
/24 | 255.255.255.0 | 256 | 254
/25 | 255.255.255.128 | 128 | 126
/26 | 255.255.255.192 | 64 | 62
/27 | 255.255.255.224 | 32 | 30
/28 | 255.255.255.240 | 16 | 14
/29 | 255.255.255.248 | 8 | 6
/30 | 255.255.255.252 | 4 | 2
Work through the binary manually a couple of times to lock in the intuition. After that, lean on ipcalc and Python for anything production-facing. No prize for mental arithmetic when a server is down.

