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

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

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:

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

References