IP Addressing, Subnets, and IPv6
Every packet on the internet and inside a cloud network carries a source and destination IP address, and every network decides what to do with it by looking at prefixes — blocks of addresses that share their leading bits. Most developers can ignore this until something breaks: two VPCs that cannot be peered because both use 10.0.0.0/16, a subnet that ran out of addresses during an autoscaling event, a service that works over IPv4 but times out for IPv6 users, or large uploads that hang while small requests succeed.
This guide covers the addressing knowledge those situations need: reading and calculating CIDR blocks, choosing and planning address ranges, how IPv6 differs, and how to diagnose the failures that addressing mistakes cause. The protocols themselves are covered in TCP/IP & Network Protocols.
TL;DR
- CIDR notation —
10.20.16.0/20— gives a network address and how many leading bits identify the network; a /20 holds 2¹² = 4,096 addresses. - In IPv4, subtract the network and broadcast addresses for usable hosts; cloud providers reserve more.
- Use private ranges (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) internally, and plan them so networks that may ever connect never overlap. - IPv6 addresses are 128 bits; subnets are almost always /64, and a single site prefix holds thousands of them.
- Dual-stack systems need IPv6 working end to end — DNS, listeners, firewalls, and logs — not just an address.
- Many "random" network failures are overlapping ranges, wrong masks, exhausted subnets, or blocked ICMP breaking MTU discovery.
Quick Example
Python's ipaddress module does subnet arithmetic reliably:
Splitting a /16 into /20s yields 16 subnets of 4,096 addresses. The last check is the one that saves projects: a partner network using 10.20.24.0/21 overlaps the application subnet, so the two cannot be connected without renumbering or address translation.
Core Concepts
IPv4 Addresses and Prefixes
An IPv4 address is 32 bits, written as four decimal octets: 10.20.16.5. A prefix length says how many leading bits identify the network; the remaining bits identify hosts within it.
Addresses in a block = 2^(32 − prefix). In a traditional IPv4 subnet, the first address identifies the network and the last is the broadcast address, so a /24 has 254 usable hosts and a /26 has 62. Cloud providers reserve more — AWS reserves five addresses in every subnet — so size subnets with headroom for scaling events.
Splitting and Aggregating
Each extra prefix bit halves the block. A /24 splits into two /25s, four /26s, or eight /27s:
The reverse — aggregation — lets one route cover many subnets: a router that knows 10.20.0.0/16 reaches all sixteen /20s above.
Private and Special Ranges
Some private ranges are effectively taken by tools: Docker's default bridge network uses 172.17.0.0/16, and home routers and VPNs commonly use parts of 192.168.0.0/16. Choosing those for corporate or cloud networks invites conflicts.
Planning Address Space
Assign non-overlapping blocks to every network that might ever need to connect: each environment, region, VPC, Kubernetes pod and service range, and on-premises site. Record allocations in an IP address management (IPAM) tool or a reviewed file. Leave room to grow — renumbering a production network later is expensive. See Cloud Networking and AWS VPC.
IPv6
Addresses
IPv6 addresses are 128 bits, written as eight groups of four hexadecimal digits. Leading zeros in a group can be dropped, and one run of all-zero groups can be replaced by :::
Prefixes and Subnets
- Subnets are /64: 64 bits of network prefix and 64 bits of interface identifier. Stateless address autoconfiguration (SLAAC) depends on it.
- A site typically receives a /48 (65,536 /64 subnets) or a /56 (256 subnets). Address scarcity, the reason for most IPv4 planning, disappears.
- Global unicast addresses are routable on the internet; firewalls, not address translation, control what is reachable.
- Every interface also has a link-local address (
fe80::/10), used for neighbor discovery and routing protocols. - Neighbor Discovery replaces ARP and relies on ICMPv6, which must not be blocked wholesale.
Dual-Stack in Practice
Most networks run IPv4 and IPv6 side by side. Clients look up both A and AAAA records in DNS and use Happy Eyeballs — racing connection attempts and preferring IPv6 if it answers quickly — so a broken IPv6 path shows up as slowness rather than outright failure. Making a service genuinely dual-stack means:
- Listening on IPv6 as well as IPv4 (
[::]and0.0.0.0). - Firewall and security group rules for both families.
- Publishing
AAAArecords only when the IPv6 path works end to end. - Logs, rate limiters, allowlists, and database columns that handle IPv6 addresses — a
VARCHAR(15)column or an IPv4-only regular expression breaks the first time an IPv6 client appears.
Some networks, especially mobile carriers, are IPv6-only and reach IPv4 services through translation (NAT64 with DNS64), which works as long as applications use hostnames rather than literal IPv4 addresses.
Diagnosing Addressing Problems
When addressing looks right but traffic still fails, capture packets to see what actually happens on the wire — see Packet Capture and Network Diagnostics.
Best Practices
Plan Ranges Before You Need Them
Allocate address space per environment and region up front, with growth room, in a shared record. The cheapest time to avoid an overlap is before the second network exists.
Size Subnets for Peaks
Autoscaling, rolling deployments, and per-pod addressing in Kubernetes consume addresses quickly. Size subnets for peak demand plus provider reservations, not for today's instance count. See Kubernetes Networking.
Use Proper Types for Addresses
Store addresses in types that understand both families, such as PostgreSQL's inet and cidr, and parse them with library functions rather than string handling.
Allow the ICMP That Networks Need
Path MTU discovery depends on ICMP "fragmentation needed" (IPv4) and "packet too big" (IPv6) messages, and IPv6 neighbor discovery runs over ICMPv6. Filter ICMP selectively instead of blocking it entirely.
Common Mistakes
The Same Default Range Everywhere
IPv4-Only Assumptions in Code
Publishing AAAA Records Without IPv6 Service
Blocking All ICMP
FAQ
How do I calculate the number of hosts in a subnet?
For IPv4, the block holds 2^(32 − prefix) addresses; subtract two for the network and broadcast addresses to get usable hosts — 254 for a /24, 62 for a /26. Cloud providers reserve additional addresses, so check their documentation.
What does CIDR notation mean?
Classless Inter-Domain Routing notation writes a network as an address plus a prefix length, such as 10.20.16.0/20. The prefix length is the number of leading bits shared by every address in the block.
Why are IPv6 subnets /64?
IPv6 reserves 64 bits for the interface identifier, which stateless address autoconfiguration and several other mechanisms rely on. Address space is plentiful, so using /64 everywhere costs nothing and keeps the network predictable.
Do I need NAT with IPv6?
Usually not. IPv6 provides enough addresses for every device to have a globally unique one, and firewalls control reachability. Translation still appears in specific roles, such as NAT64 for reaching IPv4-only services from IPv6-only networks.
Which private IPv4 range should we use?
Any RFC 1918 range works technically. In practice, choose blocks inside 10.0.0.0/8 from a central plan, and avoid 172.17.0.0/16 and common home-router ranges in 192.168.0.0/16 that collide with Docker and VPN users.
Related Topics
- TCP/IP & Network Protocols — The protocols that carry these addresses
- Networking — Networking fundamentals for developers
- Cloud Networking — VPCs, subnets, and connectivity in the cloud
- AWS VPC — Address planning and subnets on AWS
- Kubernetes Networking — Pod and service address ranges
- DNS — A and AAAA records and name resolution
- Packet Capture and Network Diagnostics — Seeing what happens on the wire
- BGP and Internet Routing — How prefixes are routed across the internet
- LAN Switching, VLANs, and Segmentation — VLANs and segments behind subnets