Skip to content

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.

Runs in your browser. Your inputs are not uploaded.Open formulaRules updated November 2026
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.

Jump to results

Your inputs

Mode
Network
IPv4, /8 to /28 (plan and split modes), for example 10.0.0.0/16.
Sets the reserved addresses per subnet and the subnet size limits.
Plan mode. A per-zone tier gets one equal subnet in every zone.
Tiers and growth
Plan mode, one tier per line. kind is public, private, data or custom; size is IP addresses per zone (app:private:4000) or a fixed prefix (spoke-a:custom:/20); add :single for one subnet in the whole VPC.
Multiplies each subnet's required IPs so it can grow in place. 1 = no cushion.
Kubernetes
Adds the nodes' and pods' address demand to one tier.
A tier name. Left empty, the first private tier is used.
Include nodes that upgrades add (surge nodes).
Maximum pods per node the CNI is set to allow.
AWS VPC CNI only: spare addresses kept ready (WARM_IP_TARGET). The CNI's default keeps a whole network interface warm.
Peer ranges
Plan mode, one CIDR per line. These ranges are kept out of the allocation and reported if they overlap the base.
Split mode
Split mode. A power of two gives equal parts; any other number uses the next power of two and lists the spare blocks.
Split mode. A prefix such as 20 splits a /16 into sixteen /20 blocks. It wins over the number of parts.
Check mode
Check mode, one CIDR per line. Every pair is reported as disjoint, equal, or one containing the other.

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.
Allocated
28,032
42.8% of 65,536 addresses
Free
37,504
largest block 10.0.128.0/17
Subnets
9
3 tiers
AWS reserves
5 per subnet
a /24 has 251 usable

Address map of 10.0.0.0/16

appappapp, zone a: 10.0.0.0/19, 8,192 addresses (8,187 usable), sized to 97.7% fullaapp, zone b: 10.0.32.0/19, 8,192 addresses (8,187 usable), sized to 97.7% fullbapp, zone c: 10.0.64.0/19, 8,192 addresses (8,187 usable), sized to 97.7% fullcdatadatadata, zone a: 10.0.96.0/22, 1,024 addresses (1,019 usable), sized to 98.1% fulldata, zone b: 10.0.100.0/22, 1,024 addresses (1,019 usable), sized to 98.1% fulldata, zone c: 10.0.104.0/22, 1,024 addresses (1,019 usable), sized to 98.1% fullpublicpublicpublic, zone a: 10.0.108.0/25, 128 addresses (123 usable), sized to 81.3% fullpublic, zone b: 10.0.108.128/25, 128 addresses (123 usable), sized to 81.3% fullpublic, zone c: 10.0.109.0/25, 128 addresses (123 usable), sized to 81.3% fullFreeFreeFree: 10.0.109.128/25, 128 addressesFree: 10.0.110.0/23, 512 addressesFree: 10.0.112.0/20, 4,096 addressesFree: 10.0.128.0/17, 32,768 addresses10.0.0.010.0.64.010.0.128.010.0.192.010.0.255.255
  • 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

9 subnets on AWS, largest at the lowest address
TierZoneCIDRFirst usableLast usableAddressesUsableDemandUtilizationSized forHeadroom
appa10.0.0.0/1910.0.0.410.0.31.2548,1928,1874,00048.9%97.7%4,187
appb10.0.32.0/1910.0.32.410.0.63.2548,1928,1874,00048.9%97.7%4,187
appc10.0.64.0/1910.0.64.410.0.95.2548,1928,1874,00048.9%97.7%4,187
dataa10.0.96.0/2210.0.96.410.0.99.2541,0241,01950049.1%98.1%519
datab10.0.100.0/2210.0.100.410.0.103.2541,0241,01950049.1%98.1%519
datac10.0.104.0/2210.0.104.410.0.107.2541,0241,01950049.1%98.1%519
publica10.0.108.0/2510.0.108.410.0.108.1261281235040.7%81.3%73
publicb10.0.108.128/2510.0.108.13210.0.108.2541281235040.7%81.3%73
publicc10.0.109.0/2510.0.109.410.0.109.1261281235040.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

4 free blocks, the fewest aligned CIDRs that cover what is left
BlockAddressesUsable as one AWS subnet
10.0.109.128/25128123
10.0.110.0/23512507
10.0.112.0/204,0964,091
10.0.128.0/1732,76832,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

Reserved addresses and subnet limits per cloud, read from the providers' own documentation
CloudReserved per subnetWhich addressesSubnet sizesBase block sizesResize a subnet later?Checked
AWS5network address, VPC router, DNS, future use, and the broadcast address/16 to /28/16 to /28No2026-11-05
Google Cloud4network address, default gateway, second-to-last address (future use), and the broadcast address/4 to /29/8 to /28Yes2026-11-05
Azure5network address, default gateway, two DNS mapping addresses, and the broadcast address/2 to /29/8 to /28Yes2026-11-05
Generic IPv42network address and broadcast address/8 to /32/8 to /28Yes2026-11-05
IP addresses one Kubernetes node takes from its subnet (P = pods per node, w = warm IPs per node)
Networking modeIPs per nodePods use subnet addresses?Belongs toChecked
AWS VPC CNI (secondary IPs)1 + P + wYesaws2026-11-05
AWS VPC CNI (prefix delegation)1 + 16 × (ceil(P ÷ 16) + 1)Yesaws2026-11-05
Azure CNI (node subnet)1 + PYesazure2026-11-05
Overlay CNI (separate pod range)1Noany2026-11-05
Azure CNI Overlay1Noazure2026-11-05
GKE alias IP (VPC-native)1Nogcp2026-11-05
Private and shared address ranges used for the non-private warning
RangeNameChecked
10.0.0.0/8RFC 1918 10/82026-11-05
172.16.0.0/12RFC 1918 172.16/122026-11-05
192.168.0.0/16RFC 1918 192.168/162026-11-05
100.64.0.0/10Shared address space (RFC 6598)2026-11-05
Where the rules come from
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/
Hidden gotchas
TopicWhat catches people out
Reserved addressesAWS and Azure reserve 5 addresses in every subnet and Google Cloud reserves 4, so a /28 on AWS has 11 usable addresses, not 16.
ResizingAn 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.
PeeringVPC peering, transit gateways and VPN tunnels need non-overlapping ranges, and renumbering a live network is the expensive way to find that out.
Pod addressesThe AWS VPC CNI gives every pod a VPC address, so a few large nodes can use up a subnet that looked generous.
Warm IPsWarm-IP and warm-prefix settings reserve addresses nobody is using yet: with prefix delegation a node can hold up to 15 idle addresses.
AlignmentA block must start at a multiple of its own size, so packing small subnets first strands space the larger ones can no longer use.
IPv6IPv6 does not remove IPv4 dependencies: load balancers, endpoints and many services still need IPv4 addresses in the subnet.

Three ways to reduce this number

  1. Enable prefix delegation or use an overlay CNI so pods stop consuming subnet addresses.
  2. Add a secondary CIDR such as 100.64.0.0/10 for pods (AWS accepts blocks from it) instead of growing the main range.
  3. 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.