VPC subnet calculator: split a CIDR block and plan IP exhaustion
Split a base CIDR into aligned subnets per tier and zone, see them on a map, and find out whether you will run out of IP addresses.
How to verify this
Open your browser's network tab and change an input: nothing is sent. The page computes with the formulas and the dated price table below. The same engine answers the API and the MCP tool, so you can reproduce any scenario from code.
Your /16 is 42.8% allocated across 9 subnets; the largest free block is 10.0.128.0/17.
- Heads-up:All 9 subnets are above 80% of usable addresses; growth_factor is 2.
- Heads-up:An AWS subnet's IPv4 CIDR cannot be changed after it is created, and 6 of 9 subnets are above 90% of usable addresses (app/a, app/b, app/c, data/a, data/b, data/c). Pick a longer-lived size now, or plan to replace the subnet.
Address map of 10.0.0.0/16
- app
- data
- public
- Free space
Position along each row is the address, left to right. Hover a block for its CIDR. A bold outline marks a subnet sized to 80% full or more.
Subnets
| Tier | Zone | CIDR | First usable | Last usable | Addresses | Usable | Demand | Utilization | Sized for | Headroom |
|---|---|---|---|---|---|---|---|---|---|---|
| app | a | 10.0.0.0/19 | 10.0.0.4 | 10.0.31.254 | 8,192 | 8,187 | 4,000 | 48.9% | 97.7% | 4,187 |
| app | b | 10.0.32.0/19 | 10.0.32.4 | 10.0.63.254 | 8,192 | 8,187 | 4,000 | 48.9% | 97.7% | 4,187 |
| app | c | 10.0.64.0/19 | 10.0.64.4 | 10.0.95.254 | 8,192 | 8,187 | 4,000 | 48.9% | 97.7% | 4,187 |
| data | a | 10.0.96.0/22 | 10.0.96.4 | 10.0.99.254 | 1,024 | 1,019 | 500 | 49.1% | 98.1% | 519 |
| data | b | 10.0.100.0/22 | 10.0.100.4 | 10.0.103.254 | 1,024 | 1,019 | 500 | 49.1% | 98.1% | 519 |
| data | c | 10.0.104.0/22 | 10.0.104.4 | 10.0.107.254 | 1,024 | 1,019 | 500 | 49.1% | 98.1% | 519 |
| public | a | 10.0.108.0/25 | 10.0.108.4 | 10.0.108.126 | 128 | 123 | 50 | 40.7% | 81.3% | 73 |
| public | b | 10.0.108.128/25 | 10.0.108.132 | 10.0.108.254 | 128 | 123 | 50 | 40.7% | 81.3% | 73 |
| public | c | 10.0.109.0/25 | 10.0.109.4 | 10.0.109.126 | 128 | 123 | 50 | 40.7% | 81.3% | 73 |
Utilization is today's demand over usable addresses. Sized for is the demand after the growth factor, which is what the prefix was chosen to hold. Highlighted rows are 80% full or more when sized for.
A subnet's IPv4 CIDR cannot be changed after it is created. A VPC's CIDR block cannot be resized either, only extended with secondary blocks (a secondary block may come from 100.64.0.0/10).
Free space
| Block | Addresses | Usable as one AWS subnet |
|---|---|---|
| 10.0.109.128/25 | 128 | 123 |
| 10.0.110.0/23 | 512 | 507 |
| 10.0.112.0/20 | 4,096 | 4,091 |
| 10.0.128.0/17 | 32,768 | 32,763 |
Terraform
locals {
subnet_cidrs = {
"app-a" = cidrsubnet("10.0.0.0/16", 3, 0)
"app-b" = cidrsubnet("10.0.0.0/16", 3, 1)
"app-c" = cidrsubnet("10.0.0.0/16", 3, 2)
"data-a" = cidrsubnet("10.0.0.0/16", 6, 24)
"data-b" = cidrsubnet("10.0.0.0/16", 6, 25)
"data-c" = cidrsubnet("10.0.0.0/16", 6, 26)
"public-a" = cidrsubnet("10.0.0.0/16", 9, 216)
"public-b" = cidrsubnet("10.0.0.0/16", 9, 217)
"public-c" = cidrsubnet("10.0.0.0/16", 9, 218)
}
}
How it is calculated
Block arithmetic (32-bit integers)
mask = 2^32 − 2^(32−p) network = address AND mask broadcast = network OR NOT mask size = 2^(32−p)
Usable addresses
usable = size − reserved reserved: AWS 5, Azure 5, Google Cloud 4, generic 2 (generic: a /31 has 2 usable, a /32 has 1)
Kubernetes demand per node (P pods per node, w warm IPs)
AWS VPC CNI 1 + P + w AWS VPC CNI prefix 1 + 16 × (ceil(P ÷ 16) + 1) Azure CNI 1 + P Overlay, Azure Overlay 1 GKE alias IP 1, plus one /24 pod range per node (returned separately)
Required IPs and prefix
r = ceil((tier demand + Kubernetes demand) × growth_factor)
prefix = the longest p whose usable count is at least r,
kept inside the cloud's subnet range (AWS /28 to /16)Allocation and free space
Sort subnets by size, largest first (ties: tier order, then zone). Place each at the lowest free address that is a multiple of its size. Ranges in overlap_with are removed from free space first. Free space is returned as the fewest aligned CIDR blocks.
Health, overlap and Terraform
utilization = demand ÷ usable projected = ceil(demand × growth_factor) ÷ usable a and b overlap when a.network ≤ b.broadcast and b.network ≤ a.broadcast newbits = p − p_base netnum = (network − network_base) ÷ 2^(32−p) cidrsubnet(base, newbits, netnum)
Assumptions
- Everything is IPv4 bit arithmetic on the numbers you enter. Nothing is looked up and nothing leaves the page.
- Subnets are sized for the projected demand (demand × growth_factor); the table also shows today's demand, utilization and headroom.
- SUBNET_NEAR_EXHAUSTION compares projected demand with usable addresses (80% or more); AWS_SUBNET_NOT_RESIZABLE fires above 90%.
- A tier with a fixed prefix (spoke-a:custom:/20) keeps that prefix; if Kubernetes demand needs a larger block, the larger block wins.
- Kubernetes rows are planning formulas from the CNI documentation: the node's own address, its pods and the warm addresses. Extra network interfaces' own addresses and upgrade surge nodes are not counted unless you add them to the node count.
- GKE pod ranges use the default of one /24 per node, which supports up to 110 pods per node.
- IPv6 follows AWS rules: a /56 per VPC and a /64 per subnet, so a VPC holds 256 subnets.
- The reserved-address and subnet-size rules were read from each provider's documentation on 2026-11-05 and are reviewed yearly.
The data behind it
| Cloud | Reserved per subnet | Which addresses | Subnet sizes | Base block sizes | Resize a subnet later? | Checked |
|---|---|---|---|---|---|---|
| AWS | 5 | network address, VPC router, DNS, future use, and the broadcast address | /16 to /28 | /16 to /28 | No | 2026-11-05 |
| Google Cloud | 4 | network address, default gateway, second-to-last address (future use), and the broadcast address | /4 to /29 | /8 to /28 | Yes | 2026-11-05 |
| Azure | 5 | network address, default gateway, two DNS mapping addresses, and the broadcast address | /2 to /29 | /8 to /28 | Yes | 2026-11-05 |
| Generic IPv4 | 2 | network address and broadcast address | /8 to /32 | /8 to /28 | Yes | 2026-11-05 |
| Networking mode | IPs per node | Pods use subnet addresses? | Belongs to | Checked |
|---|---|---|---|---|
| AWS VPC CNI (secondary IPs) | 1 + P + w | Yes | aws | 2026-11-05 |
| AWS VPC CNI (prefix delegation) | 1 + 16 × (ceil(P ÷ 16) + 1) | Yes | aws | 2026-11-05 |
| Azure CNI (node subnet) | 1 + P | Yes | azure | 2026-11-05 |
| Overlay CNI (separate pod range) | 1 | No | any | 2026-11-05 |
| Azure CNI Overlay | 1 | No | azure | 2026-11-05 |
| GKE alias IP (VPC-native) | 1 | No | gcp | 2026-11-05 |
| Range | Name | Checked |
|---|---|---|
| 10.0.0.0/8 | RFC 1918 10/8 | 2026-11-05 |
| 172.16.0.0/12 | RFC 1918 172.16/12 | 2026-11-05 |
| 192.168.0.0/16 | RFC 1918 192.168/16 | 2026-11-05 |
| 100.64.0.0/10 | Shared address space (RFC 6598) | 2026-11-05 |
| Source |
|---|
| https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html |
| https://docs.aws.amazon.com/vpc/latest/userguide/vpc-cidr-blocks.html |
| https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_planning_network_topology_ip_subnet_allocation.html |
| https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/planning-ipv6-adoption-in-the-aws-cloud-network.html |
| https://learn.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq |
| https://docs.cloud.google.com/vpc/docs/subnets |
| https://www.rfc-editor.org/rfc/rfc3021 |
| https://www.rfc-editor.org/rfc/rfc1918 |
| https://www.rfc-editor.org/rfc/rfc6598 |
| https://docs.aws.amazon.com/eks/latest/best-practices/ip-opt.html |
| https://docs.aws.amazon.com/eks/latest/best-practices/prefix-mode-linux.html |
| https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/docs/prefix-and-ip-target.md |
| https://learn.microsoft.com/en-us/azure/aks/concepts-network-ip-address-planning |
| https://learn.microsoft.com/en-us/azure/aks/azure-cni-overview |
| https://docs.cloud.google.com/kubernetes-engine/docs/concepts/alias-ips |
| https://docs.tigera.io/calico/latest/networking/configuring/vxlan-ipip |
| https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/ |
| Topic | What catches people out |
|---|---|
| Reserved addresses | AWS and Azure reserve 5 addresses in every subnet and Google Cloud reserves 4, so a /28 on AWS has 11 usable addresses, not 16. |
| Resizing | An AWS subnet's IPv4 CIDR cannot be changed after it is created, so a subnet that is too small means a new subnet and a migration. |
| Peering | VPC peering, transit gateways and VPN tunnels need non-overlapping ranges, and renumbering a live network is the expensive way to find that out. |
| Pod addresses | The AWS VPC CNI gives every pod a VPC address, so a few large nodes can use up a subnet that looked generous. |
| Warm IPs | Warm-IP and warm-prefix settings reserve addresses nobody is using yet: with prefix delegation a node can hold up to 15 idle addresses. |
| Alignment | A block must start at a multiple of its own size, so packing small subnets first strands space the larger ones can no longer use. |
| IPv6 | IPv6 does not remove IPv4 dependencies: load balancers, endpoints and many services still need IPv4 addresses in the subnet. |
Last updated 2026-11-05 (dataset 2026-11, refreshed yearly).
- https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html
- https://docs.aws.amazon.com/vpc/latest/userguide/vpc-cidr-blocks.html
- https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_planning_network_topology_ip_subnet_allocation.html
- https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/planning-ipv6-adoption-in-the-aws-cloud-network.html
- https://learn.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq
- https://docs.cloud.google.com/vpc/docs/subnets
- https://www.rfc-editor.org/rfc/rfc3021
- https://www.rfc-editor.org/rfc/rfc1918
- https://www.rfc-editor.org/rfc/rfc6598
- https://docs.aws.amazon.com/eks/latest/best-practices/ip-opt.html
- https://docs.aws.amazon.com/eks/latest/best-practices/prefix-mode-linux.html
- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/docs/prefix-and-ip-target.md
- https://learn.microsoft.com/en-us/azure/aks/concepts-network-ip-address-planning
- https://learn.microsoft.com/en-us/azure/aks/azure-cni-overview
- https://docs.cloud.google.com/kubernetes-engine/docs/concepts/alias-ips
- https://docs.tigera.io/calico/latest/networking/configuring/vxlan-ipip
- https://docs.cilium.io/en/stable/network/concepts/ipam/cluster-pool/
Three ways to reduce this number
- Enable prefix delegation or use an overlay CNI so pods stop consuming subnet addresses.
- Add a secondary CIDR such as 100.64.0.0/10 for pods (AWS accepts blocks from it) instead of growing the main range.
- Leave aligned free space instead of packing the base block full, so a subnet can be added later without renumbering.
Use it from code
The same engine is available as a REST endpoint and as an MCP tool named calc_cidr_vpc_subnet_planner. Your scenario as an API call:
curl -X POST 'https://api.x12i.com/v1/calc/cidr-vpc-subnet-planner' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"input": {
"mode": "plan",
"base_cidr": "10.0.0.0/16",
"cloud": "aws",
"az_count": 3,
"ipv6": false,
"tiers": [
"app:private:4000",
"data:private:500",
"public:public:50"
],
"growth_factor": 2,
"k8s_cni": "none",
"k8s_nodes_per_az": 10,
"k8s_pods_per_node": 30,
"k8s_warm_ips_per_node": 5,
"overlap_with": [],
"split_count": 4,
"cidrs": [
"10.0.0.0/16",
"10.0.1.0/24",
"192.168.0.0/16"
]
},
"options": {
"explain": false
}
}' Schema: GET /v1/calc/cidr-vpc-subnet-planner/schema
Frequently asked questions
How many usable IPs does a /24 have on AWS?
251. A /24 has 256 addresses and AWS reserves five in every subnet: the network address, the VPC router, DNS, one for future use and the broadcast address. Azure also reserves five (251 usable); Google Cloud reserves four (252 usable).
How do I split a /16 into subnets?
Each extra bit of prefix halves a block: a /17 is half of a /16 and a /20 is one sixteenth, 4,096 addresses. Pick a prefix per tier from the addresses it needs plus growth, then place the largest subnets first, each at an address that is a multiple of its size. Plan mode does this for every tier and zone; split mode cuts one block into equal parts, and Terraform's cidrsubnet(base, newbits, netnum) names each one.
How many IPs do EKS pods use?
With the default AWS VPC CNI every pod takes one address from its node's subnet, so a node uses 1 + pods + warm IPs. In prefix mode the CNI hands out /28 blocks of 16 addresses and keeps one spare block, so a node running 30 pods holds 1 + 16 × (2 + 1) = 49. An overlay CNI moves pods to a separate range, and then a node uses one subnet address.