IPv4 Subnetting Tutorial: How to Calculate Subnets Without Losing Your Mind

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

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 ipcalc or 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 to 10.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.

Share: