Build1 distinct publisher3 min readPublished
Most VPC debugging is guesswork because the topology arrived as a module someone else wrote. The arithmetic that replaces the guessing is small, but the one number you cannot revise afterwards is the prefix at the top.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
Do the arithmetic on the recommended layout before you inherit it.
A /16 is 2^16 addresses, or 65,536 [1]. A /20 is 2^12, or 4,096 [2], and AWS takes five out of every subnet for the network address, the VPC router, DNS, one reserved slot and broadcast [4], leaving 4,091 usable [3]. Three worker subnets at /20, one per availability zone, gives 12,273 usable addresses [4], and the /16 above them holds sixteen /20s in total [5].
That last figure is the whole EKS argument. Under the VPC CNI every pod can consume an ENI-backed IP, and the dev.to walkthrough calls IP exhaustion one of the most common EKS production incidents [9]. The 4,091 figure is a pod ceiling per zone, shared with rolling deployments that run old and new pods at once [8], not a node ceiling. For the /20 default to transfer to your cluster, steady-state pod count plus deploy surge has to sit under about four thousand per zone. If it does not, the fix is a wider prefix, and the prefix is the part you cannot revise once peering or Transit Gateway attachments exist [6].
The sizing rule has a rounding edge. Round the host requirement up to the next power of two and subtract the exponent from 32, so 300 hosts becomes 512, which is 2^9, which gives /23 [5]. The rule counts addresses, not usable ones. A /23 is 512 total and 507 after the reserves [6], so a requirement written as "512 hosts" is met on paper and five short in the subnet. Five addresses is not much of a shortfall until the person who wrote the requirement meant it.
Routing is where the "public subnet" abstraction misleads. A subnet is public because its route table carries 0.0.0.0/0 to an internet gateway, matched most-specific-first against an implicit local route for the full VPC CIDR that cannot be removed [11][12]. In Terraform, the table and the route do nothing to a subnet on their own; aws_route_table_association is what binds them and makes routing take effect [13]. The sample table in the walkthrough is tagged Name = "rtb-public" and Tier = "public" [22]. Those tags describe the subnet but do not route a single packet. A module that creates the table and skips the association leaves you a subnet that reads public in the console and behaves private on the wire.
Egress runs through two translations, not one [20]. For a private instance at 10.0.2.15 reaching a public registry:
1. The private route table sends 0.0.0.0/0 to the NAT gateway [19]. 2. The NAT gateway rewrites the source to its own Elastic IP and an ephemeral port [19]. 3. The NAT gateway's own public subnet route table sends the packet to the internet gateway [19]. 4. The internet gateway performs a separate 1:1 translation [19].
Step three is why the NAT gateway has to sit in a public subnet at all: it needs its own route to the IGW [21]. And because the public IP mapping lives at the gateway rather than on the ENI, `ip addr` on an instance never shows its public address [15]. That constraint matters for diagnosis, not as a curiosity: when you work the inbound checklist of public IP on the ENI, default route to the IGW, and security group plus NACL permitting the port [16], you cannot confirm the first item from inside the box. Any one of the three missing returns the same silent timeout with no pointer to the cause, which is why the walkthrough treats them as a single list rather than three troubleshooting paths [17].
Ranked by verification strength, evidence, and original report placement.
With the EKS VPC CNI, every pod can consume an ENI-backed IP; the walkthrough calls IP exhaustion one of the most common EKS production incidents and gives /20 per AZ for worker subnets as the standard starting point.
Three things must all be true for inbound internet access: the instance has a public or Elastic IP on its ENI, the subnet's route table has 0.0.0.0/0 to the IGW, and both the security group and the NACL allow the inbound traffic on that port.
Any one of the three inbound conditions missing produces the same symptom, a silent timeout with no obvious pointer to the actual cause, and the walkthrough says this is where most "why can't I reach my instance" tickets originate.
A CIDR block is an IP address plus a prefix length; the prefix length fixes the network portion and the remaining bits are host space.
Total addresses in a block are given by 2^(32 - prefix).
AWS reserves 5 addresses per subnet: the network address, the VPC router, DNS, one reserved address, and broadcast.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 27, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
The three AWS defaults on your bill that nobody actually chose1 distinct publisher
build
Send kills, not scores: the leaderboard fix that turns anti-cheat into a schema decision1 distinct publisher
build
ALB validates the JWT, Keycloak decides what is in it: the Terraform for the matching realm1 distinct publisher
build
Express Mode builds the ALB you skipped, and owns the knobs you used to write1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Checkable with a calculator, unchecked against AWS
Roughly half of this rests on arithmetic a reader can verify unaided — the address counts, the reserved-address subtraction, the 12,273 across three zones — and it holds up. The other half is platform behaviour described from memory: the five reserved addresses, one IGW per VPC, the NAT gateway's placement requirement. None of it is cited to AWS documentation, and the one place the numbers turn on themselves is the /23 example, where dev.to's own reserved-address rule leaves the answer five hosts short of the question.
No adoption to read
There is nothing here that adoption could be measured against. No release, no version, no deployment, no fleet or usage figure — the only artifact is a Terraform snippet the author wrote to illustrate an association. The /20-per-AZ figure is called a standard starting point, but standard according to whom is never established, so treating it as evidence of practice would be inventing a fact the reporting does not contain.
The superlatives outrun the arithmetic
The headline advice is unusually modest — pick a bigger prefix, it costs nothing — and modest advice is hard to oversell. The overstatement sits in three unquantified words: 'most common' incident, 'most' tickets, 'standard' starting point. Each turns one engineer's experience into a statement about how often something happens across the industry, and the sizing prescriptions that follow rest on precisely those three words rather than on anything counted. A narrow gap, then, but it leans the same way every time.
Attention, not a vendor pitch
The piece ends by naming five things the fuller version covers, which tells you what it is: a summary written to pull readers onward. That is a real incentive and it shapes the edit — the connection-tracking limits and the S3 endpoint cost trap, the details with the most operational bite, are held back rather than developed. What is absent is money. Nothing is being sold, no vendor is named as a solution, and the /16 recommendation costs the author nothing to give and the reader nothing to take.
Firm on mechanics, soft on frequency
Confidence splits cleanly along one line. Where the story explains how routing, translation and address space work, it is internally consistent and independently checkable, so we can stand behind it. Where it tells you how often things go wrong, it is a single practitioner's recollection with one publisher behind it and no second account in this reporting to test it against.