By default, the AWS VPC CNI plugin assigns each EKS pod its own private VPC IP from your subnet. That gives pods direct VPC connectivity but caps the pod density per node at the instance type's ENI/IP limit. An m5.large can run 29 pods. An m5.xlarge can run 58. For dense microservice workloads, that is way too few.
In 2021, AWS introduced prefix delegation for the VPC CNI: instead of one IP per pod, ENIs receive entire /28 prefixes (16 IPs each). This raises the per-node pod limit to 110+ for almost any instance type — a 4-16x density improvement that often eliminates the need for larger nodes.
This article explains how prefix delegation works, when to use it, the tradeoffs, and the production configuration patterns.
The original ENI/IP limit problem
Without prefix delegation, the VPC CNI plugin works like this:
- Each EC2 instance has a fixed maximum number of ENIs.
- Each ENI can hold a fixed number of secondary IPs.
- Total pod IPs available = (ENIs - 1) × IPs_per_ENI + (IPs_per_ENI - 1).
- (One IP per ENI is used by the ENI itself; the primary ENI's primary IP is used by the node.)
| Instance type | ENIs | IPs/ENI | Max pods (no PD) | Max pods (with PD) |
|---|---|---|---|---|
| m5.large | 3 | 10 | 29 | 110 |
| m5.xlarge | 4 | 15 | 58 | 110 |
| m5.2xlarge | 4 | 15 | 58 | 110 |
| m5.4xlarge | 8 | 30 | 234 | 250 |
| m5.8xlarge | 8 | 30 | 234 | 250 |
| c5.large | 3 | 10 | 29 | 110 |
| r5.large | 3 | 10 | 29 | 110 |
Note the cliff at large instance sizes — m5.large to m5.2xlarge all hit the 110 kubelet default with prefix delegation, even though without PD the IP capacity scales linearly. This means prefix delegation often lets you run smaller, cheaper instances at the same pod count.
How prefix delegation works
Instead of assigning individual IPs to an ENI, prefix delegation assigns /28 prefixes (16 addresses each). The math becomes:
- Each ENI can hold a fixed number of prefixes (instead of IPs).
- Each prefix gives 16 pod IPs (a /28).
- So an ENI that previously held 10 IPs now holds 10 prefixes = 160 IPs.
The prefix is just a contiguous range of IPs in your subnet that this ENI "owns." Pods on that node take IPs from the prefix.
Enabling prefix delegation
It is an environment variable on the VPC CNI daemonset:
kubectl set env daemonset aws-node \ -n kube-system \ ENABLE_PREFIX_DELEGATION=true
Or via Helm chart values, or via the EKS addon configuration if you manage the CNI as an EKS addon. After enabling, new nodes use prefix delegation immediately. Existing nodes continue with their original IP allocation until they are recycled.
Warm prefix targets
Prefix delegation introduces tuning around how many prefixes to pre-fetch on each node. The relevant settings:
| Variable | Default | Purpose |
|---|---|---|
| WARM_PREFIX_TARGET | 1 | Keep N extra prefixes warm beyond current need |
| MINIMUM_IP_TARGET | - | Minimum free IPs (overrides prefix-based logic) |
| WARM_IP_TARGET | - | Keep N free IPs warm |
The default of WARM_PREFIX_TARGET=1 means each node has at least one fully-spare prefix ready for pod scheduling. For a node that runs 50 pods steady-state, the CNI may hold 5 prefixes (80 IPs) — using 50, with 30 "wasted" as warm capacity.
For tighter VPC space, lower WARM_PREFIX_TARGET to 0 and use MINIMUM_IP_TARGET=10 to keep just 10 IPs warm regardless of prefix count.
Subnet sizing with prefix delegation
The math for subnet sizing changes when prefixes are involved. Each node consumes one or more /28 prefixes (16 IPs each). For a 100-node cluster:
- Worst case (max density, lots of warm prefixes): each node holds 7 prefixes = 112 IPs. 100 nodes × 112 = 11,200 IPs needed.
- Typical: each node holds 3-4 prefixes = 48-64 IPs. 100 nodes × 56 = 5,600 IPs needed.
That's a substantial chunk of any subnet. The pattern most teams use is to give EKS its own subnet (or set of per-AZ subnets) sized as /20 (4,091 usable AWS) or /19 (8,187 usable). Or, even better, put pods in a CGNAT secondary VPC CIDR — see our Kubernetes pod CIDR sizing article for the full pattern.
When NOT to use prefix delegation
- Very low pod density. If you only run 5-10 pods per node, the prefix overhead wastes IPs. Stick with individual IP assignment.
- Subnets are already tight on space. Prefix delegation needs contiguous /28s in your subnet. If your subnet is fragmented or near-full, you may not be able to allocate them.
- You use security groups for pods. With pod-level security groups, every pod gets its own ENI (with its own primary IP). Prefix delegation does not apply.
- You are on Nitro-generation instances only. Prefix delegation requires Nitro-generation instances; older instance types (m4, c4, r4) do not support it.
Bottlerocket and self-managed nodes
Prefix delegation works on:
- Amazon Linux 2 / 2023 EKS-optimized AMIs — supported since 2021
- Bottlerocket — supported, automatically configured
- EKS managed node groups — supported when CNI version is recent enough
- Self-managed node groups — supported, configure manually via bootstrap script
- Karpenter-provisioned nodes — supported, set on the CNI daemonset
The pod density limit (MAX_PODS) is set by the kubelet startup. The EKS-optimized AMI has a script /etc/eks/max-pods-calculator.sh that computes this. Older versions of the script do not know about prefix delegation; update the AMI or override MAX_PODS manually.
Operational gotchas
- Fragmented subnets reject prefix allocation. If your subnet has individual IPs scattered around (from non-PD pods, ENIs, lambda, etc.), AWS may not find a contiguous /28 to delegate. Solve by giving EKS dedicated subnets.
- Node startup time can increase if the CNI has to allocate many prefixes for warming. Tune
WARM_PREFIX_TARGETdown if startup matters. - IPv6 mode is separate. EKS IPv6 clusters work differently — every pod gets an IPv6 address out of a /80 delegated to the ENI. No /28 prefixes involved.
Calculator workflow
Our Cloud calculator in EKS mode computes the right subnet size given:
- Target node count
- Target pods per node
- Whether prefix delegation is enabled
- Warm prefix target
Use it to plan a new EKS subnet allocation before applying.
Key takeaways
- Prefix delegation raises the per-node pod limit from 29 (m5.large) to 110+ by handing ENIs
/28prefixes (16 IPs each) instead of individual IPs. - Enable with
ENABLE_PREFIX_DELEGATION=trueon the aws-node daemonset. - Each EKS node typically holds 3-7 /28 prefixes (48-112 IPs) under default warm target settings.
- Tune
WARM_PREFIX_TARGETandMINIMUM_IP_TARGETfor tighter IP usage at the cost of slower pod scheduling. - Combine with CGNAT secondary VPC CIDRs to keep pod IPs separate from VM/RDS address space.