Worked example · AWS VPC · two availability zones
AWS Three-Tier VPC Subnet Plan
A 10.0.0.0/16 VPC split into public, application and data subnets in two availability zones, sized for 250 hosts each and packed under AWS reservations.
The plan
parent 10.0.0.0/16 subnets 6 allocated 1,536 of 65,536 (2.3%) free 64,000
Largest first: public-a takes the first /24 (256 addresses), so every smaller block that follows starts on a multiple of its own size with no gaps.
| Name | Hosts | Subnet | Netmask | Usable range | Broadcast | Usable | Unused |
|---|---|---|---|---|---|---|---|
| public-a | 250 | 10.0.0.0/24 | 255.255.255.0 | 10.0.0.4 – 10.0.0.254 | 10.0.0.255 | 251 | 1 |
| app-a | 250 | 10.0.1.0/24 | 255.255.255.0 | 10.0.1.4 – 10.0.1.254 | 10.0.1.255 | 251 | 1 |
| data-a | 250 | 10.0.2.0/24 | 255.255.255.0 | 10.0.2.4 – 10.0.2.254 | 10.0.2.255 | 251 | 1 |
| public-b | 250 | 10.0.3.0/24 | 255.255.255.0 | 10.0.3.4 – 10.0.3.254 | 10.0.3.255 | 251 | 1 |
| app-b | 250 | 10.0.4.0/24 | 255.255.255.0 | 10.0.4.4 – 10.0.4.254 | 10.0.4.255 | 251 | 1 |
| data-b | 250 | 10.0.5.0/24 | 255.255.255.0 | 10.0.5.4 – 10.0.5.254 | 10.0.5.255 | 251 | 1 |
Free blocks: 10.0.6.0/23 10.0.8.0/21 10.0.16.0/20 10.0.32.0/19 10.0.64.0/18 10.0.128.0/17
How the plan maps to the VPC
The six subnets are allocated in input order because they are all the same size, so each availability zone gets the same public–application–data sequence:
| Zone | Tier | Subnet | Typical use |
|---|---|---|---|
| a | public | 10.0.0.0/24 | Load balancer nodes, NAT gateway |
| a | application | 10.0.1.0/24 | Application instances |
| a | data | 10.0.2.0/24 | Database subnet group |
| b | public | 10.0.3.0/24 | Load balancer nodes, NAT gateway |
| b | application | 10.0.4.0/24 | Application instances |
| b | data | 10.0.5.0/24 | Database subnet group |
The 250-host request fits a /24 with room to spare: AWS leaves 251 usable addresses after reserving the first four and the last. The planner reports the usable range as .4 to .254, which is the range you can hand to instances.
Why this layout
- Two zones, three tiers. Each tier exists in both zones, so an application load balancer and a database subnet group can span the VPC without sharing a subnet across zones.
- Equal /24s. Same-size requests keep their input order, which keeps the zone and tier mapping readable. Larger tiers can be placed first with their own host counts; the planner always packs largest first.
- AWS reservations are part of the math. Capacity rule “AWS VPC” reserves five addresses per subnet and enforces the /16–/28 bounds, so the table and the AWS/CloudFormation exports agree.
- Growth. 10.0.0.0/16 holds 256 /24s; this plan uses six, leaving 250 for more zones, endpoints or shared services.
Check the finished ranges in the VLSM planner, or inspect a single subnet in the subnet calculator. The Azure version of this exercise is the hub-spoke example.
Questions
How many /24 subnets does a /16 VPC hold?
256. A /16 fixes the first 16 bits, so the remaining 8 bits give 28 = 256 /24 blocks. This plan uses six of them and leaves the rest for growth.
Why does each subnet show 251 usable addresses instead of 254?
AWS reserves five addresses in every subnet: the first four (network, VPC router, DNS and a future-use address) and the last (broadcast). A /24 therefore has 256 − 5 = 251 usable addresses, and the planner reports the usable range as .4 to .254.
Why are the three tiers packed in the same order in each availability zone?
Requests of equal size keep the order you entered, so public, application and data subnets are allocated sequentially in each zone. That makes the mapping from subnet to availability zone and tier predictable in route tables and security groups.
Can the same VPC grow beyond two availability zones?
Yes. The plan uses 6 of the 256 /24s in 10.0.0.0/16. A third zone can repeat the same three-tier pattern from 10.0.6.0/24, and the planner shows the remaining free space.