You spin up a VPC in AWS and it asks for a CIDR block. You type 10.0.0.0/16 because that's what the tutorial said. Then you create a subnet and it wants another one, so you put 10.0.1.0/24. It works. You move on.
Six months later somebody asks why the subnet can only hold 251 usable addresses when you asked for 256, and whether 10.0.1.0/24 overlaps with the 10.0.0.0/22 block the networking team just allocated. You don't know. Nobody does. Everyone quietly opens a subnet calculator.
The slash number is not arbitrary syntax. It encodes exactly how the address space is carved up, and once you can read it directly you stop needing the calculator.
Before CIDR: the class system
An IPv4 address is 32 bits. Written as four decimal numbers separated by dots, each number represents one byte: 192.168.1.10 is really 11000000.10101000.00000001.00001010.
Some of those bits identify the network. The rest identify a specific host inside that network. Routers care only about the network portion, which is what lets them forward a packet toward the right general destination without knowing about every individual machine on the internet.
The question is where the boundary between the two sits. In 1981, the answer was baked into the address itself. This was classful addressing, defined in RFC 791, and it recognized three usable classes.
- Class A: first bit is
0. The first byte is the network, the remaining three are hosts. 128 networks on paper, each holding roughly 16.7 million addresses. Range0.0.0.0to127.255.255.255. - Class B: first two bits are
10. Two bytes network, two bytes host. 16,384 networks of 65,536 addresses. Range128.0.0.0to191.255.255.255. - Class C: first three bits are
110. Three bytes network, one byte host. Roughly 2 million networks of 256 addresses. Range192.0.0.0to223.255.255.255.
Two of those 128 Class A networks were never assignable. 0.0.0.0/8 was reserved to mean "this network" and 127.0.0.0/8 was reserved for loopback, which is why 127.0.0.1 resolves to your own machine. That left 126 usable Class A allocations for the entire world, and organizations that received one in the early 1980s (IBM, Ford, MIT, the US Postal Service) held blocks of 16.7 million addresses each.
Class D (224.0.0.0 onward) was reserved for multicast and Class E for experimental use. Neither was allocated to organizations.
The elegance was that a router could determine the network boundary by inspecting the leading bits of the address. No extra information needed to travel alongside it. In an era of expensive memory and slow processors, that mattered.
Why the class system broke
The problem is visible the moment you write the three sizes next to each other. You could have 256 addresses, 65,536 addresses, or 16.7 million addresses. Nothing in between.
A university with 800 machines could not use a Class C. So it received a Class B and used a little over 1 percent of it. The other 64,700 addresses were allocated, unusable by anyone else, and permanently idle.
This was address exhaustion, and by 1992 the projections were alarming. Class B space was on track to run out within a couple of years. The internet had roughly 1.3 million connected hosts and was doubling annually.
A second problem was growing alongside it. Every Class C network needed its own entry in the global routing table, because there was no way to express "these 16 adjacent Class C networks all go the same direction." Backbone routers were accumulating tens of thousands of routes with no mechanism for compression. Router memory and lookup time were becoming the binding constraint on internet growth.
Two exhaustion problems, then: addresses running out, and routing tables growing faster than hardware could handle. Both traced back to the same cause, which was that the network/host boundary was fixed at three arbitrary positions.
The fix: move the boundary anywhere
CIDR, Classless Inter-Domain Routing, was specified in RFC 1518 and RFC 1519 in September 1993. The core idea is a single sentence: stop deriving the network boundary from the address, and carry it explicitly instead.
That explicit value is the prefix length, written after a slash. 192.168.1.0/24 means the first 24 bits are the network portion. 10.0.0.0/8 means the first 8 bits are. 203.0.113.64/26 means the first 26, which is a boundary that falls in the middle of the fourth byte and would have been unrepresentable under the class system.
The prefix length can be any value from 0 to 32. That gives 33 possible block sizes instead of 3, each one exactly half the size of the one before it.
Everything else follows mechanically. Host bits are whatever remains: 32 - prefix. The block size is 2^host_bits. A /26 has 6 host bits and therefore 64 addresses. A /30 has 2 host bits and 4 addresses.
Reading a block without a calculator
Three numbers describe any CIDR block, and all three come from the prefix length alone.
Total addresses is 2^(32-prefix). Usable addresses is that minus two, because the first address in the block is the network address (it names the network itself) and the last is the broadcast address (packets sent to it reach every host on the segment).
The subnet mask is the prefix written as a 32-bit number with all the network bits set to 1 and all the host bits set to 0. A /24 is 24 ones followed by 8 zeros, which in dotted decimal is 255.255.255.0.
| Prefix | Mask | Addresses | Usable | Typical use |
|---|---|---|---|---|
/8 | 255.0.0.0 | 16,777,216 | 16,777,214 | Entire private range 10.0.0.0/8 |
/16 | 255.255.0.0 | 65,536 | 65,534 | A whole VPC |
/20 | 255.255.240.0 | 4,096 | 4,094 | Large subnet |
/24 | 255.255.255.0 | 256 | 254 | Standard subnet or office LAN |
/26 | 255.255.255.192 | 64 | 62 | Small subnet tier |
/30 | 255.255.255.252 | 4 | 2 | Point-to-point link |
/31 | 255.255.255.254 | 2 | 2 | Point-to-point (RFC 3021) |
/32 | 255.255.255.255 | 1 | 1 | Single host, firewall rules |
The /31 is a special case. A point-to-point link has exactly two endpoints and no need for a broadcast address, so RFC 3021 permits using both addresses in a /31 as hosts. Without it, every link between two routers would waste half a /30.
The /32 is the other useful extreme. It matches exactly one address, which makes it the standard way to express a single host in firewall rules and route tables. When you see 203.0.113.7/32 in a security group, it means that one machine and nothing else.
Where blocks can start
A CIDR block cannot begin at an arbitrary address. It must start on a boundary that is a multiple of its own size.
A /24 holds 256 addresses, so it must start at a multiple of 256 in the last byte: 10.0.0.0, 10.0.1.0, 10.0.2.0. A /26 holds 64, so within a single /24 the only valid starting points are .0, .64, .128, and .192.
Writing 192.168.1.100/26 is malformed. The block would run from .100 to .163, crossing the .128 boundary, and the prefix bits would no longer uniquely identify the network. Most tools will silently correct it to 192.168.1.64/26 or reject it outright.
The reason is that routing decisions are made with a bitwise AND. A router takes the destination address, ANDs it with the mask, and compares the result to the network address. That only works if the host bits in the network address are all zero, which is exactly what alignment guarantees.
Route aggregation
The other half of CIDR's value has nothing to do with allocation efficiency. It is about keeping the global routing table survivable.
Consider four adjacent networks: 203.0.112.0/24, 203.0.113.0/24, 203.0.114.0/24, and 203.0.115.0/24. Under classful routing these are four separate Class C networks and require four routing table entries, even if every packet for all four leaves through the same router.
With CIDR, if the four blocks are adjacent and aligned, they can be advertised as a single 203.0.112.0/22. One entry replaces four. This is route aggregation, sometimes called route summarization or supernetting.
The effect compounds. An ISP holding a /16 can hand out hundreds of customer subnets internally while advertising exactly one prefix to the rest of the internet. The outside world does not need to know or care how the space is divided inside.
This is why CIDR allocations follow geography and provider hierarchy rather than being handed out first-come-first-served. Aggregation only works when the blocks that belong together are numerically adjacent. Regional registries allocate contiguous ranges to providers specifically so those providers can summarize.
Longest prefix match
Aggregation creates an obvious question. If a router holds both 203.0.112.0/22 and a more specific 203.0.113.0/24, and a packet arrives for 203.0.113.50, both entries match. Which one wins?
The rule is longest prefix match: the entry with the most network bits takes priority. The /24 beats the /22 because 24 is more specific than 22.
This is the mechanism behind almost every routing behavior you encounter. The default route 0.0.0.0/0 matches every possible address with zero prefix bits, which makes it the least specific entry and therefore the last resort. Anything more specific overrides it.
It is also how traffic engineering works in practice. An organization advertising a /20 to two providers can advertise a more specific /24 out of that range to just one of them, and traffic for that /24 will prefer that path everywhere on the internet. Deaggregation for the sake of steering traffic is common, and it is also a significant contributor to routing table growth.
Where you meet CIDR
Cloud networking is the most common encounter. A VPC is defined by a CIDR block, usually a /16 from private space, and subnets carve it into smaller aligned pieces. Cloud providers reserve extra addresses inside each subnet: AWS takes five per subnet rather than two, which is why a /24 subnet gives you 251 usable addresses instead of 254.
Firewall and security group rules use CIDR notation for source and destination ranges. 0.0.0.0/0 means the entire internet, which is why seeing it on an SSH ingress rule is an incident. A single host is /32. An office range might be 198.51.100.0/24.
The private address ranges defined in RFC 1918 are themselves CIDR blocks: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The middle one is a good demonstration of why classless allocation matters, since a /12 covers 172.16.x.x through 172.31.x.x and has no classful equivalent at all.
Kubernetes uses CIDR blocks for pod and service networks, and network policies express allowed traffic in CIDR terms. Container runtimes allocate per-node pod ranges by subdividing a cluster-wide block.
IPv6 uses the same notation with a 128-bit address space. Prefix lengths run from 0 to 128, a typical end-site allocation is a /48, and a single LAN segment is conventionally a /64. The classful era left no residue in IPv6; it was classless from the start.
Summary
CIDR's real contribution was not a new notation. It was recognizing that the network/host boundary is an allocation decision, not a property of the address, and that fixing it in the address format meant every allocation had to be rounded up to one of three sizes.
Making the boundary explicit solved both crises at once. Variable prefix lengths meant an organization needing 500 addresses could receive a /23 instead of wasting a Class B, which slowed address exhaustion enough to buy the roughly thirty years it has taken IPv6 to reach meaningful deployment. Hierarchical, aggregatable allocation meant routing table growth could be decoupled from the number of connected networks, which is the only reason backbone routers remained buildable as the internet scaled.
Once the slash number stops being a magic value and becomes what it actually is, a count of fixed leading bits, everything downstream follows: the block size, the valid starting addresses, the mask, and which route wins when several match.
Part of the Explained series: concepts in tech, clearly.