Free lesson · System Design Fundamentals
IP Addresses
Lesson 3.2 - IP Addresses
The second lesson of Module 3.
Every machine on a network needs an address - a unique identifier so other machines can find it and send data to it. That's an IP address - the Layer 3 (Network) addressing scheme that makes the internet work. It's how every packet knows where to go. Two versions exist: IPv4 (the one you've seen - 192.168.1.42) and IPv6 (the one slowly replacing it - 2001:0db8:85a3::8a2e:0370:7334). For system design, you also need to understand CIDR notation - the shorthand for describing ranges of addresses - because it appears in every cloud networking configuration: VPCs, subnets, security groups, and firewall rules.
IPv4: The Address Space We Exhausted
Interactive animation: NAT: a whole office behind one public address.
An IPv4 address is a 32-bit number, written as four octets (bytes) separated by dots - the dotted decimal format:
192.168.1.42
Each octet: 0-255 (8 bits)
Total address space: 2³² = 4,294,967,296 (~4.3 billion addresses)
4.3 billion sounded like an unlimited supply when IPv4 was designed in 1981. It's not enough now - there are more internet-connected devices than IPv4 addresses. Smartphones, laptops, servers, IoT sensors, smart home devices - the global device count exceeds 15 billion. IPv4 addresses were fully exhausted by the regional internet registries between 2011 and 2019.
How the internet copes: NAT (Network Address Translation). Your home router has one public IPv4 address (assigned by your ISP). Behind it, every device in your home gets a private address (192.168.1.x). When your phone sends a request to the internet, the router translates the private address to the public address, adding a unique port number to track which device the response should go back to. This lets thousands of devices share one public IP. NAT is an ingenious workaround - and the reason IPv4 has survived decades past its expiration date.
Private vs Public Addresses
Interactive animation: Private ranges inside the VPC, one public door out.
Three address ranges are reserved for private networks - they're not routable on the public internet:
| Range | CIDR | Addresses | Common use |
|---|---|---|---|
10.0.0.0 - 10.255.255.255 |
10.0.0.0/8 |
16.7 million | Cloud VPCs (AWS, GCP, Azure), large corporate networks |
172.16.0.0 - 172.31.255.255 |
172.16.0.0/12 |
1 million | Medium corporate networks, Docker default networking |
192.168.0.0 - 192.168.255.255 |
192.168.0.0/16 |
65,536 | Home networks, small offices |
Why this matters for system design: your database at 10.0.3.42 is reachable within your VPC but invisible to the public internet. Your API server at 54.23.100.1 (a public IP) is reachable by anyone. This separation is the basic network security model - internal services (databases, caches, message queues) live on private IPs behind a firewall; only the load balancer or API gateway has a public IP.
flowchart TD
Internet["🌐 Public Internet"]
subgraph VPC["VPC (10.0.0.0/16)"]
subgraph Public_Subnet["Public Subnet (10.0.1.0/24)"]
LB["Load Balancer\nPublic: 54.23.100.1\nPrivate: 10.0.1.10"]
end
subgraph Private_Subnet["Private Subnet (10.0.2.0/24)"]
API1["API Server 1\n10.0.2.11"]
API2["API Server 2\n10.0.2.12"]
end
subgraph DB_Subnet["Database Subnet (10.0.3.0/24)"]
DB["PostgreSQL\n10.0.3.42"]
Redis["Redis\n10.0.3.43"]
end
end
Internet -->|"only public IP\nis accessible"| LB
LB --> API1 & API2
API1 & API2 --> DB & Redis
style Internet fill:#fb7185,stroke:#f43f5e,color:#000
style LB fill:#fbbf24,stroke:#f59e0b,color:#000
style DB fill:#34d399,stroke:#10b981,color:#000
style Redis fill:#34d399,stroke:#10b981,color:#000
A VPC network architecture diagram. The VPC uses the private address range 10.0.0.0/16, providing 65,536 private addresses. Inside the VPC, three subnets are configured. The public subnet (10.0.1.0/24) contains the load balancer, which has both a public IP (54.23.100.1, reachable from the internet) and a private IP (10.0.1.10). The private subnet (10.0.2.0/24) contains two API servers at 10.0.2.11 and 10.0.2.12 - these have no public IPs and are unreachable from the internet directly. The database subnet (10.0.3.0/24) contains PostgreSQL at 10.0.3.42 and Redis at 10.0.3.43 - also unreachable from the internet. Traffic flows from the internet to the load balancer (the only public entry point), from the load balancer to the API servers, and from the API servers to the databases. The database and cache are never exposed to the internet. An attacker scanning the internet can find 54.23.100.1 (the LB) but cannot find or reach 10.0.3.42 (the database). This is defense in depth through network architecture.
IPv6: The Permanent Solution
Interactive animation: Dual stack: IPv4 inside, IPv6 accepted at the edge.
An IPv6 address is 128 bits - written as eight groups of four hexadecimal digits:
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Shortened (omit leading zeros, collapse consecutive zero groups with ::):
2001:db8:85a3::8a2e:370:7334
Total address space: 2¹²⁸ = 3.4 × 10³⁸ (340 undecillion)
To put 340 undecillion in perspective: that's approximately 670 quadrillion addresses for every square millimeter of the Earth's surface. IPv6 solves the address exhaustion problem permanently - there will never be a shortage of IPv6 addresses.
Adoption status (2026): IPv6 carries over 45% of Google's global traffic. Major cloud providers, ISPs, and mobile networks fully support it. But IPv4 isn't going away - most internal networks, VPCs, and system design discussions still use IPv4 addressing. The practical approach: design for dual-stack (support both IPv4 and IPv6), use IPv4 for internal/VPC networking, and ensure external-facing services accept IPv6 traffic.
CIDR Notation: Describing Address Ranges
Interactive animation: Move the prefix length and watch the address range grow and shrink.
CIDR (Classless Inter-Domain Routing) notation describes a range of IP addresses using a prefix length:
10.0.0.0/24
The /24 means: the first 24 bits are the network prefix (fixed).
The remaining 8 bits are for host addresses (variable).
/24 → 2⁸ = 256 addresses (10.0.0.0 through 10.0.0.255)
| CIDR | Fixed bits | Host bits | Addresses | Common use |
|---|---|---|---|---|
/32 |
32 | 0 | 1 | Single host (used in security group rules) |
/28 |
28 | 4 | 16 | Tiny subnet (AWS reserves 5, leaving 11 usable) |
/24 |
24 | 8 | 256 | Standard subnet for one tier (web servers, DB servers) |
/20 |
20 | 12 | 4,096 | Large subnet |
/16 |
16 | 16 | 65,536 | Typical VPC size |
/8 |
8 | 24 | 16.7 million | Entire 10.x.x.x private range |
The rule: smaller CIDR number = bigger network. /8 is huge (16.7M addresses). /32 is one address.
Why CIDR matters for system design: every cloud VPC, subnet, security group, and network ACL uses CIDR blocks:
- VPC:
10.0.0.0/16- 65,536 addresses for your entire cloud environment - Public subnet:
10.0.1.0/24- 256 addresses for public-facing resources - Private subnet:
10.0.2.0/24- 256 addresses for application servers - Database subnet:
10.0.3.0/24- 256 addresses for data stores - Security group rule: "Allow inbound TCP/5432 from
10.0.2.0/24" - only API servers in the private subnet can reach the database port
This appears in every AWS, GCP, and Azure architecture. In system design interviews, when you draw a VPC with subnets, you're expected to assign CIDR blocks that don't overlap and allocate enough addresses for the expected instance count.
A Brandon Story: The Subnet That Ran Out
A team I'd advised configured their database subnet as /28 - 16 addresses, of which only 11 were usable (AWS reserves 5 per subnet: network address, VPC router, DNS server, future use, and broadcast). They deployed 8 database instances (primary + replicas + analytics instances). Three addresses remained.
When they needed to add 4 more instances for a traffic event (additional read replicas), the subnet had no room. The CreateDBInstance API calls failed with "insufficient IP addresses in subnet." They couldn't add the instances they needed during a production traffic spike.
The fix required creating a new, larger subnet, migrating existing instances to it, and updating all security group rules - a multi-hour operation that involved database failovers and brief connectivity interruptions. During a traffic spike.
The lesson: always allocate significantly more CIDR space than your current needs. A /24 (256 addresses) costs nothing more than a /28 (16 addresses) - the addresses are free within a VPC. But running out of addresses during a scaling event is a production-impacting constraint that's expensive and disruptive to fix. Their new subnet: /24. Their maximum database instances on that subnet: 251. Unlikely to ever be a constraint again.
General subnet sizing guidance:
- VPC:
/16(65,536 addresses) - the maximum for most cloud providers. Use it. - Per-tier subnets:
/24(256 addresses) minimum./20(4,096) if you expect significant horizontal scaling. - Never use
/28for anything that might grow. The 16-address limit is a trap. - Plan for multi-AZ: each AZ needs its own subnet, so triple your per-tier estimate.
Six Takeaways from This Lesson
-
IPv4 = 32 bits, ~4.3 billion addresses. Exhausted since 2011-2019. NAT extends its life by sharing public IPs.
-
IPv6 = 128 bits, 340 undecillion addresses. The permanent solution. 45%+ of traffic in 2026. Design for dual-stack.
-
Private IPs (10.x, 172.16.x, 192.168.x) are for internal networks - not internet-routable. This is the basic security model: databases on private IPs, only the LB on a public IP.
-
CIDR notation (
/24,/16) describes address ranges. Smaller number = bigger range. Used in every cloud networking configuration. -
CIDR matters for VPC/subnet design. Allocate
/16for the VPC,/24minimum per subnet, and plan for multi-AZ. -
Never under-allocate CIDR space. Running out of addresses during a scaling event is a production constraint that's expensive to fix. Addresses within a VPC are free - use a
/24where a/28might seem sufficient.
Try It
Exercise: Warmup (10 minutes). Run
ifconfig(macOS/Linux) oripconfig(Windows). Find your machine's IP address. Is it private (10.x, 172.16.x, 192.168.x) or public? Find your public IP by searching "what is my IP" in a browser. Why are they different?
Exercise: Core (25 minutes). Design the network architecture for a three-tier application (web, app, database) in AWS. Assign a VPC CIDR (/16), public subnet CIDR (/24) for the load balancer, two private subnet CIDRs (/24 each, in different AZs) for app servers, and two database subnet CIDRs (/24 each, in different AZs). Verify: do any CIDRs overlap?
Exercise: Stretch (30 minutes). Log into the AWS console (or GCP/Azure) and examine a VPC. Note: the VPC CIDR, the subnet CIDRs, the route tables, and the security groups. How does the route table differentiate between traffic destined for the internet vs traffic staying within the VPC?
What's Next
Lesson 3.3 covers TCP vs UDP - the two transport protocols, their trade-offs, and when each is the right choice.