Understanding CIDR Notation and Subnetting (Without the Pain)
A practical guide to CIDR notation and subnetting covering binary IP math, prefix lengths, private ranges, VPC CIDR carving, and Kubernetes subnet sizing with worked examples.
Infrastructure engineer with 10+ years building production systems on AWS, GCP,…

IP Addresses Are Just Numbers -- and CIDR Is How You Slice Them
Every time you configure a VPC, write a firewall rule, or set up a Kubernetes cluster, you're working with CIDR notation. It looks like 10.0.0.0/16 and it defines a range of IP addresses. If you've ever stared at a /24 wondering how many hosts it holds, or carved a VPC into subnets by trial and error, this guide will make subnetting feel mechanical instead of mystical.
CIDR notation is just binary math with a convenient shorthand. Once you see how it works, you'll calculate subnet sizes in your head and spot misconfigured network ranges instantly.
What Is CIDR Notation?
Definition: CIDR (Classless Inter-Domain Routing) notation is a method for representing IP address ranges using a base IP address followed by a slash and a prefix length (e.g.,
192.168.1.0/24). The prefix length indicates how many leading bits define the network portion, with the remaining bits identifying individual hosts within that network.
Before CIDR (introduced in 1993), IP addresses were divided into rigid classes: Class A (/8), Class B (/16), Class C (/24). A company either got 16 million addresses or 256 -- nothing in between. CIDR replaced this wasteful system with variable-length prefixes, letting you allocate exactly the range you need.
Binary IP Addresses: The Foundation
An IPv4 address is a 32-bit number. We write it as four octets in decimal for readability, but the computer sees binary:
IP Address: 192.168.1.0
Binary: 11000000.10101000.00000001.00000000
|--------|--------|--------|--------|
Octet 1 Octet 2 Octet 3 Octet 4
Each octet is 8 bits, ranging from 0 (00000000) to 255 (11111111). The total address space is 2^32 = 4,294,967,296 addresses.
How the Prefix Length Works
The number after the slash tells you how many bits from the left are the network portion. The remaining bits are the host portion:
192.168.1.0/24
Binary: 11000000.10101000.00000001 | 00000000
|----- 24 network bits ----| |-- 8 host bits --|
Network: 192.168.1.0
Hosts: 192.168.1.1 through 192.168.1.254
Broadcast: 192.168.1.255
Total addresses: 2^8 = 256
Usable hosts: 254 (subtract network and broadcast)
Quick Reference: Common Prefix Lengths
| CIDR | Subnet Mask | Total Addresses | Usable Hosts | Typical Use |
|---|---|---|---|---|
| /32 | 255.255.255.255 | 1 | 1 | Single host route |
| /31 | 255.255.255.254 | 2 | 2 | Point-to-point link |
| /28 | 255.255.255.240 | 16 | 14 | Small subnet |
| /24 | 255.255.255.0 | 256 | 254 | Standard LAN segment |
| /20 | 255.255.240.0 | 4,096 | 4,094 | Medium VPC subnet |
| /16 | 255.255.0.0 | 65,536 | 65,534 | Large VPC or campus |
| /8 | 255.0.0.0 | 16,777,216 | 16,777,214 | Class A (legacy) |
Pro tip: To quickly calculate the number of addresses in a CIDR block, subtract the prefix length from 32 and raise 2 to that power. A /20 has 2^(32-20) = 2^12 = 4,096 addresses. For usable hosts, subtract 2 (network address and broadcast address).
Calculating Network, Broadcast, and Host Range
Given a CIDR block, here's how to find the key addresses:
- Convert to binary -- Write out all 32 bits of the IP address.
- Split at the prefix length -- The left portion is the network prefix (fixed). The right portion is the host portion (variable).
- Network address -- Set all host bits to 0. This is the first address in the range.
- Broadcast address -- Set all host bits to 1. This is the last address in the range.
- First usable host -- Network address + 1.
- Last usable host -- Broadcast address - 1.
Worked Example: 10.50.100.0/22
IP: 10.50.100.0
Binary: 00001010.00110010.01100100.00000000
Prefix: /22 = 22 network bits, 10 host bits
Network bits: 00001010.00110010.011001 (first 22 bits)
Host bits: 00.00000000 (last 10 bits)
Network address: 00001010.00110010.01100100.00000000 = 10.50.100.0
Broadcast address: 00001010.00110010.01100111.11111111 = 10.50.103.255
First usable: 10.50.100.1
Last usable: 10.50.103.254
Total addresses: 2^10 = 1,024
Usable hosts: 1,022
Private IP Ranges (RFC 1918)
Three ranges are reserved for private networks and cannot be routed on the public internet:
| Range | CIDR | Addresses | Common Use |
|---|---|---|---|
| 10.0.0.0 -- 10.255.255.255 | 10.0.0.0/8 | 16,777,216 | Cloud VPCs, large enterprises |
| 172.16.0.0 -- 172.31.255.255 | 172.16.0.0/12 | 1,048,576 | Docker default bridge, some VPCs |
| 192.168.0.0 -- 192.168.255.255 | 192.168.0.0/16 | 65,536 | Home networks, small offices |
Watch out: When connecting VPCs via peering or VPN, overlapping CIDR ranges will cause routing conflicts. If VPC A uses 10.0.0.0/16 and VPC B also uses 10.0.0.0/16, they can't peer because the router can't distinguish which network owns which address. Plan your CIDR allocations across all environments before provisioning.
VPC CIDR Carving: A Practical Guide
Here's how I typically carve a VPC for a production AWS deployment:
Step 1: Choose the VPC CIDR
Start with a /16 (65,536 addresses) unless you know you need more or less. Use the 10.x.0.0/16 range, incrementing x for each VPC:
Production: 10.0.0.0/16
Staging: 10.1.0.0/16
Development: 10.2.0.0/16
Step 2: Divide Into Subnets by Availability Zone
For 3 AZs with public and private subnets, divide the /16 into /20 subnets (4,096 addresses each):
Public subnets:
us-east-1a: 10.0.0.0/20 (10.0.0.0 - 10.0.15.255)
us-east-1b: 10.0.16.0/20 (10.0.16.0 - 10.0.31.255)
us-east-1c: 10.0.32.0/20 (10.0.32.0 - 10.0.47.255)
Private subnets:
us-east-1a: 10.0.48.0/20 (10.0.48.0 - 10.0.63.255)
us-east-1b: 10.0.64.0/20 (10.0.64.0 - 10.0.79.255)
us-east-1c: 10.0.80.0/20 (10.0.80.0 - 10.0.95.255)
Database subnets:
us-east-1a: 10.0.96.0/24 (10.0.96.0 - 10.0.96.255)
us-east-1b: 10.0.97.0/24 (10.0.97.0 - 10.0.97.255)
us-east-1c: 10.0.98.0/24 (10.0.98.0 - 10.0.98.255)
Remaining: 10.0.99.0 - 10.0.255.255 (reserved for growth)
Step 3: Validate No Overlaps
Every subnet must be contained within the VPC CIDR, and no two subnets can overlap. This is where a CIDR calculator saves time.
# Quick subnet calculation with ipcalc
ipcalc 10.0.0.0/20
# Output: Network 10.0.0.0, Broadcast 10.0.15.255, Hosts 4094
# Python one-liner for CIDR math
python3 -c "import ipaddress; n = ipaddress.ip_network('10.0.0.0/20'); print(f'Network: {n.network_address}, Broadcast: {n.broadcast_address}, Hosts: {n.num_addresses - 2}')"
Subnetting for Kubernetes
Kubernetes clusters are particularly hungry for IP addresses. Each pod gets its own IP, and a busy node might run 100+ pods. For an EKS cluster:
- Node IPs come from the VPC subnet (one per EC2 instance).
- Pod IPs come from the VPC subnet by default (AWS VPC CNI). Each node consumes IPs equal to its pod count.
- A /20 subnet (4,094 usable IPs) supports roughly 40 nodes with 100 pods each.
- For larger clusters, use /18 or /16 subnets, or enable prefix delegation to pack more pod IPs per ENI.
Pro tip: AWS reserves 5 IP addresses per subnet (first four and last one). A /24 has 251 usable addresses, not 254. A /28 has 11, not 14. Factor this in when sizing subnets tightly.
Tools and Services for CIDR Management
| Tool | Type | Cost | Best For |
|---|---|---|---|
| ipcalc | CLI tool | Free | Quick subnet calculations |
| sipcalc | CLI tool | Free | IPv6 and advanced calculations |
| Python ipaddress | Standard library | Free | Scripting and automation |
| AWS VPC IPAM | Managed service | $0.01/hr per active IP | Multi-account IP planning |
| Infoblox | Enterprise IPAM | Contact sales | Large enterprise IP management |
| NetBox | Self-hosted IPAM | Free (open source) | Documentation and planning |
Frequently Asked Questions
What does /24 mean in CIDR notation?
The /24 means the first 24 bits of the IP address define the network, leaving the remaining 8 bits for host addresses. This gives you 256 total addresses (2^8), of which 254 are usable for hosts (the first address is the network address and the last is the broadcast address). A /24 is equivalent to the traditional Class C subnet mask 255.255.255.0.
How do I know if two CIDR blocks overlap?
Two CIDR blocks overlap if any address exists in both ranges. The easiest check: if one block's network address falls within the other block's range, they overlap. In Python: ipaddress.ip_network('10.0.0.0/16').overlaps(ipaddress.ip_network('10.0.5.0/24')) returns True because the /24 is entirely within the /16. Most cloud providers reject overlapping subnets at creation time.
What CIDR range should I use for a VPC?
Use the 10.0.0.0/8 private range, allocating a /16 per VPC (65,536 addresses). This gives you up to 256 non-overlapping VPCs (10.0.0.0/16 through 10.255.0.0/16). If you need fewer addresses, /20 (4,096) works for smaller environments. Avoid 172.16.0.0/12 unless you're sure it won't conflict with Docker's default bridge network.
Why does AWS reserve 5 IPs per subnet?
AWS reserves the first four and last IP in every subnet: the network address (.0), the VPC router (.1), the DNS server (.2), a reserved address for future use (.3), and the broadcast address (.255 for /24). This means a /28 (16 addresses) has only 11 usable. Account for these reservations when sizing subnets, especially small ones for NAT gateways or load balancers.
What is the difference between /31 and /32?
A /32 is a single IP address -- there are no host bits. It's used for host routes in routing tables, not for subnets. A /31 contains exactly 2 addresses and is specifically designed for point-to-point links between two routers (RFC 3021). With only two devices and a direct link, there's no need for network or broadcast addresses, so both addresses are usable.
How does CIDR relate to subnet masks?
CIDR notation and subnet masks express the same information differently. A /24 equals 255.255.255.0. The subnet mask is the prefix length expressed as a 32-bit number with the first N bits set to 1. CIDR notation is more compact and is the standard for modern infrastructure. If you see a subnet mask, count the 1-bits to convert: 255.255.240.0 has 20 ones, so it's /20.
Can I change a VPC's CIDR range after creation?
On AWS, you can add secondary CIDR blocks to an existing VPC (up to 5 by default), but you cannot modify or remove the primary CIDR. On GCP, subnets can be expanded (increase the range) but not shrunk. Plan your CIDR allocation generously upfront. It's much easier to allocate a /16 and use a fraction of it than to restructure a /24 that ran out of addresses while services are running.
Conclusion
CIDR notation is binary math dressed in convenient shorthand. Remember the formula -- 2^(32 - prefix) gives you total addresses -- and the rest follows. Allocate VPCs with /16 blocks from the 10.x.0.0 range, carve subnets into /20 for workloads and /24 for databases, leave room for growth, and verify no overlaps before you peer anything. Use ipcalc or Python's ipaddress module to automate calculations instead of doing binary math by hand. The biggest subnetting mistakes aren't math errors -- they're undersizing your initial allocation and having to restructure a live network later.
Written by
Abhishek Patel
Infrastructure engineer with 10+ years building production systems on AWS, GCP, and bare metal. Writes practical guides on cloud architecture, containers, networking, and Linux for developers who want to understand how things actually work under the hood.
Related Articles
DNS Explained: From Domain Name to IP Address, Step by Step
DNS translates domain names into IP addresses in milliseconds. Trace the full resolution chain step by step, learn every record type, and debug common failures like NXDOMAIN and SERVFAIL.
12 min read
NetworkingWhat is BGP? The Protocol That Runs the Internet
A comprehensive guide to BGP covering autonomous systems, route selection, BGP hijacking, RPKI, anycast routing, and how 75,000 independent networks form a single navigable internet.
11 min read
NetworkingLoad Balancing Algorithms: Round Robin, Least Connections, and More
A practical guide to load balancing algorithms -- round robin, least connections, IP hash, consistent hashing, and power of two choices -- with nginx and HAProxy configurations.
10 min read
Enjoyed this article?
Get more like this in your inbox. No spam, unsubscribe anytime.