CIDR Notation and Subnetting Explained for Developers

If you've ever set up a VPC, configured a firewall rule, or stared at a 10.0.0.0/16 in a Kubernetes manifest and wondered what the /16 means — this guide is for you.

Subnetting isn't just for network engineers. As a developer, you encounter CIDR notation in cloud configs, Docker networks, security groups, and API rate-limiting rules. Let's break it down.

IP Addresses in Binary

An IPv4 address is a 32-bit number, split into four 8-bit octets. We write it in dotted decimal for readability:

192.168.1.100

In binary:
11000000 . 10101000 . 00000001 . 01100100
   192        168         1        100

Each octet ranges from 0 (00000000) to 255 (11111111). Understanding this binary representation is the key to understanding everything that follows.

What Is CIDR Notation?

CIDR stands for Classless Inter-Domain Routing. The notation 192.168.1.0/24 means:

The number after the slash tells you how many bits (from the left) identify the network. The remaining bits identify individual hosts on that network.

192.168.1.0/24

11000000.10101000.00000001 | 00000000
<--- 24 bits: network ---> | <- 8 bits: hosts ->

Network: 192.168.1.0
Host range: 192.168.1.1 – 192.168.1.254
Broadcast: 192.168.1.255
Usable hosts: 254

Quick maths: A /n network has 2^(32-n) total addresses. Subtract 2 (network address + broadcast) for usable hosts. So /24 = 2^8 = 256 total, 254 usable.

Subnet Masks Decoded

A subnet mask is just another way to express the same thing as CIDR notation. The mask has 1s for the network bits and 0s for the host bits:

CIDRSubnet MaskBinary Mask
/8255.0.0.011111111.00000000.00000000.00000000
/16255.255.0.011111111.11111111.00000000.00000000
/24255.255.255.011111111.11111111.11111111.00000000
/28255.255.255.24011111111.11111111.11111111.11110000
/32255.255.255.25511111111.11111111.11111111.11111111

To find the network address, AND the IP with the mask. To find the broadcast address, OR the IP with the inverse mask.

Calculating a Network Range

Let's work through 10.0.5.0/22 step by step:

IP:        10.0.5.0
CIDR:      /22 → 22 network bits, 10 host bits

Step 1: Subnet mask
/22 = 11111111.11111111.11111100.00000000 = 255.255.252.0

Step 2: Network address (IP AND mask)
00001010.00000000.00000101.00000000  (10.0.5.0)
11111111.11111111.11111100.00000000  (255.255.252.0)
= 00001010.00000000.00000100.00000000 = 10.0.4.0

Step 3: Broadcast address (network OR inverse mask)
00001010.00000000.00000100.00000000  (10.0.4.0)
00000000.00000000.00000011.11111111  (inverse mask)
= 00001010.00000000.00000111.11111111 = 10.0.7.255

Result:
Network:    10.0.4.0
First host: 10.0.4.1
Last host:  10.0.7.254
Broadcast:  10.0.7.255
Usable:     2^10 - 2 = 1022 hosts

Watch out: The network address in CIDR notation isn't always the "obvious" one. 10.0.5.0/22 starts at 10.0.4.0, not 10.0.5.0. Always compute the network address by ANDing with the mask.

Common CIDR Blocks

CIDRAddressesUsable HostsTypical Use
/3211Single host (loopback, host route)
/281614Small subnet, point-to-point links
/24256254Standard LAN, most common subnet
/204,0964,094Medium VPC subnet
/1665,53665,534Large VPC, corporate network
/816,777,21616,777,214Class A (10.0.0.0/8 private range)

Private IP Ranges (RFC 1918)

These ranges are reserved for private networks and are not routable on the public internet:

10.0.0.0/8        10.0.0.0 – 10.255.255.255     (16M addresses)
172.16.0.0/12     172.16.0.0 – 172.31.255.255    (1M addresses)
192.168.0.0/16    192.168.0.0 – 192.168.255.255  (65K addresses)

Real-World Examples

AWS VPC

# Create a VPC with a /16 (65,534 usable IPs)
aws ec2 create-vpc --cidr-block 10.0.0.0/16

# Public subnet: /24 (254 hosts)
aws ec2 create-subnet --cidr-block 10.0.1.0/24

# Private subnet: /20 (4,094 hosts)
aws ec2 create-subnet --cidr-block 10.0.16.0/20

Kubernetes Pod CIDR

# Cluster pod network (large range for many pods)
--pod-network-cidr=10.244.0.0/16

# Service CIDR (smaller, for ClusterIP services)
--service-cidr=10.96.0.0/12

Docker Networks

# Default bridge: 172.17.0.0/16
# Create a custom network with a specific subnet
docker network create --subnet=192.168.100.0/24 my-network

Security Groups / Firewall Rules

# Allow SSH from a single IP
--cidr 203.0.113.42/32

# Allow HTTP from any IP
--cidr 0.0.0.0/0

# Allow traffic from an internal subnet only
--cidr 10.0.1.0/24

Tip: 0.0.0.0/0 matches every IPv4 address. It's the "allow all" CIDR. Use it carefully in security rules — it opens traffic to the entire internet.

Supernetting (Aggregation)

Supernetting is the reverse of subnetting — combining smaller networks into a larger one. It's used to simplify routing tables:

# These four /24 networks:
192.168.0.0/24
192.168.1.0/24
192.168.2.0/24
192.168.3.0/24

# Can be summarised as one /22:
192.168.0.0/22

This works because all four networks share the same first 22 bits. Supernetting only works when the networks are contiguous and aligned on a power-of-two boundary.

IPv6 CIDR (Brief)

IPv6 uses the same CIDR notation but with 128-bit addresses:

# A /64 subnet (standard for a single LAN)
2001:db8:abcd:0012::/64

# A /48 allocation (typical ISP assignment to a site)
2001:db8:abcd::/48

The principles are identical — the prefix length tells you how many bits are the network part. The main difference is scale: a single /64 has 2^64 addresses (18 quintillion), so you never need to worry about running out of host addresses within a subnet.

Calculate Subnets Instantly

BoltKit's SubnetCalc tool lets you enter any CIDR block and instantly see the network range, subnet mask, usable hosts, and binary breakdown. Free to use on iPhone and iPad.

Get BoltKit Free