IPv4 vs IPv6
The Complete Comparison
LinkedIn Hook
Every developer has heard of IPv4 and IPv6. Almost none can answer the follow-up question: what actually changed?
It is not just "more addresses." The two protocols differ in security, header structure, address configuration, broadcast behavior, and how they handle fragmentation.
Here is the side-by-side that every software engineer should have committed to memory:
- Address space: 32-bit (4.3 billion) vs 128-bit (340 undecillion)
- Header: IPv4 has a variable-length header with a checksum field; IPv6 has a fixed 40-byte header with no checksum
- Security: IPSec is optional in IPv4, mandatory in IPv6
- NAT: Required in IPv4 to extend address space; unnecessary in IPv6 (every device gets a public address)
- Broadcast: IPv4 has broadcast (
255.255.255.255); IPv6 abolished it — multicast covers every use case- Configuration: IPv4 needs DHCP; IPv6 can self-configure via SLAAC
This lesson is the reference card you will reach for before every system design interview.
Full lesson → [link]
#Networking #IPv4 #IPv6 #BackendEngineering #SystemDesign #InterviewPrep
What You'll Learn
- Side-by-side comparison of IPv4 and IPv6 across every major attribute
- Why the IPv6 header is simpler than IPv4 despite IPv6 being more capable
- Why adoption of IPv6 has been slow despite IPv4 exhaustion
- As a developer, where you will actually encounter each protocol
The Analogy That Makes This Click
IPv4 and IPv6 are like two generations of the same highway system.
IPv4 is the original highway built in the 1960s — it works, everyone knows how to drive on it, every car (device) is built for it, but the on-ramps are jammed, there are not enough lanes (addresses), and the signage system has workarounds bolted on top of workarounds (NAT).
IPv6 is a new highway built beside it — more lanes than you could ever fill, cleaner signage, built-in security features, no need for workarounds. The problem: every car, every road sign, every toll booth, and every GPS system has to be updated to understand the new road. Until they all are, both highways run in parallel — dual stack.
The transition is expensive and slow. But the destination is not optional.
The Full Comparison Table
| Feature | IPv4 | IPv6 |
|---|---|---|
| Address size | 32 bits | 128 bits |
| Total addresses | ~4.3 billion | ~340 undecillion |
| Address notation | Dotted decimal (192.168.1.1) | Hex colon (2001:db8::1) |
| Header size | Variable (20–60 bytes) | Fixed (40 bytes) |
| Header checksum | Yes (recalculated at every hop) | No (removed for performance) |
| Fragmentation | Done by routers and senders | Done only by senders (Path MTU Discovery) |
| Broadcast | Yes (255.255.255.255) | No — replaced by multicast |
| Multicast | Optional, limited | Built-in, required |
| Anycast | Limited support | First-class feature |
| NAT | Required to extend address space | Not needed (all devices get public IPs) |
| IPSec | Optional | Mandatory in the spec |
| Address configuration | Manual or DHCP | SLAAC (automatic) or DHCPv6 |
| Loopback | 127.0.0.1 (entire /8 block reserved) | ::1 (single address) |
| Private ranges | RFC 1918 (10.x, 172.16.x, 192.168.x) | Unique Local (fc00::/7) |
| DNS record | A record | AAAA record |
| Packet size (MTU) | Minimum 576 bytes | Minimum 1280 bytes |
| Deployment status | Universally deployed | Partial — ~40–45% of internet traffic |
Header Differences
IPv4 Header (20–60 bytes, variable)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├───────────────────────────────────────────────────────────────────┤
│Version│ IHL │DSCP/ECN│ Total Length │
├───────────────────────────────────────────────────────────────────┤
│ Identification │Flags│ Fragment Offset │
├───────────────────────────────────────────────────────────────────┤
│ Time to Live (TTL)│ Protocol│ Header Checksum │
├───────────────────────────────────────────────────────────────────┤
│ Source IP Address │
├───────────────────────────────────────────────────────────────────┤
│ Destination IP Address │
├───────────────────────────────────────────────────────────────────┤
│ Options (variable, 0–40 bytes) │
└───────────────────────────────────────────────────────────────────┘
- Variable length due to optional Options field (IHL field tells you where the header ends)
- Header Checksum — routers must recalculate it at every hop because TTL changes
- Fragmentation fields (Identification, Flags, Fragment Offset) — routers can fragment packets mid-path
- Options — rarely used but add complexity
IPv6 Header (fixed 40 bytes)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├───────────────────────────────────────────────────────────────────┤
│Version│ Traffic Class │ Flow Label │
├───────────────────────────────────────────────────────────────────┤
│ Payload Length │ Next Header │ Hop Limit │
├───────────────────────────────────────────────────────────────────┤
│ │
│ Source IPv6 Address (128 bits) │
│ │
│ │
├───────────────────────────────────────────────────────────────────┤
│ │
│ Destination IPv6 Address (128 bits) │
│ │
│ │
└───────────────────────────────────────────────────────────────────┘
- Fixed 40 bytes — no options field, no variable length
- No checksum — removed because Layer 2 (Ethernet CRC) and Layer 4 (TCP/UDP checksum) already cover integrity. Removing it means routers no longer recalculate checksums at every hop — a performance win
- No fragmentation — routers never fragment IPv6 packets. Senders use Path MTU Discovery to find the minimum MTU along the path and send packets that fit. If a router receives a packet that is too big, it drops it and sends an ICMPv6 "Packet Too Big" message back to the sender
- Extension headers replace Options — they are chained via the Next Header field, only processed by the endpoint, not every router
Why NAT Exists (and Why IPv6 Eliminates It)
The NAT Problem
In IPv4, there are not enough public addresses for every device. The solution: one public IP per household/organization, with many private IPs behind it. NAT (Network Address Translation) on the router rewrites packet headers to make this work.
What NAT breaks:
- End-to-end connectivity: devices behind NAT cannot be reached from the internet without port forwarding
- Stateful tracking: the NAT router must remember every outbound connection to map responses back
- Some protocols: VoIP, peer-to-peer, and some gaming protocols break under NAT and require special NAT traversal techniques (STUN, TURN)
- IPv4 header integrity: NAT modifies source IP, which is why IPSec cannot be used transparently through NAT without special support (NAT-T)
IPv6 Eliminates the Root Cause
With 340 undecillion addresses, every device on earth can have a globally unique, publicly routable IPv6 address. No NAT is required. End-to-end connectivity is restored. Firewalls are still needed for security — but NAT as an address-conservation mechanism is unnecessary.
Why IPv6 Adoption Is Slow
Despite IPv4 exhaustion being declared in 2011, as of 2025 IPv6 carries roughly 40–45% of global internet traffic. The reasons are structural:
-
NAT extended IPv4's life. By allowing thousands of devices to share one public IP, NAT reduced the urgency of migration. It works well enough for most consumer scenarios.
-
Dual stack is expensive. Running both protocols simultaneously doubles the operational surface — two routing tables, two sets of firewall rules, two DNS record types, double the testing surface.
-
Network equipment replacement. Older routers, switches, and firewalls may not support IPv6 or require firmware updates. Enterprise hardware replacement cycles can be 5–10 years.
-
ISP and hosting provider inertia. Until customers demand IPv6, ISPs have little commercial pressure to upgrade. The enterprise procurement cycle slows everything down.
-
Legacy application compatibility. Some applications hardcode IPv4 address strings, use libraries that do not support IPv6, or rely on IPv4-specific behavior.
-
No hard cutover. Unlike Y2K (which had a hard deadline), there is no forced switch-off date for IPv4. Dual stack means the old protocol just keeps running alongside the new one.
Where You Will Encounter Each Protocol as a Developer
IPv4 — Where You Still See It
- Internal services: Most internal microservices, databases, and message queues communicate over IPv4 on private ranges
- Legacy APIs: Any API or service that predates widespread IPv6 deployment will likely be IPv4
- Configuration files: Firewall rules, nginx upstreams, load balancer configs — predominantly still IPv4
- Docker networking: Docker's default bridge network (
172.17.0.0/16) is IPv4 - DNS A records: When you
dig example.com, you get an IPv4 A record back
IPv6 — Where You Increasingly See It
- Cloud VPCs: AWS, GCP, and Azure all support and encourage dual stack VPCs
- Mobile networks: Carrier networks (especially in Asia and North America) have transitioned heavily to IPv6
- DNS AAAA records: Major services (Google, Facebook, Cloudflare) serve AAAA records — your browser prefers IPv6 via Happy Eyeballs
- Kubernetes: Kubernetes has dual stack support; many clusters expose services on both protocols
- CDNs: Cloudflare, Fastly, and Akamai edge nodes are reachable over IPv6
- Google services: All Google infrastructure is reachable via IPv6
Code Example — Detecting and Handling Both Protocols in Node.js
const net = require("net");
const dns = require("dns").promises;
// Resolve a hostname to both IPv4 and IPv6 addresses
async function resolveAll(hostname) {
console.log(`\nResolving: ${hostname}`);
try {
const ipv4 = await dns.resolve4(hostname); // A records
console.log(` IPv4 (A records): ${ipv4.join(", ")}`);
} catch {
console.log(` IPv4 (A records): none`);
}
try {
const ipv6 = await dns.resolve6(hostname); // AAAA records
console.log(` IPv6 (AAAA records): ${ipv6.join(", ")}`);
} catch {
console.log(` IPv6 (AAAA records): none`);
}
}
// Detect address family of a given string
function detectAddressFamily(address) {
if (net.isIPv4(address)) return "IPv4";
if (net.isIPv6(address)) return "IPv6";
return "Not an IP address";
}
// Check if an IPv4 address is private (RFC 1918)
function isPrivateIPv4(address) {
const octets = address.split(".").map(Number);
const [a, b] = octets;
return (
a === 10 ||
(a === 172 && b >= 16 && b <= 31) ||
(a === 192 && b === 168)
);
}
// Server that logs client IP and protocol version
function startServer(port) {
const server = net.createServer((socket) => {
const clientIP = socket.remoteAddress;
const family = detectAddressFamily(
clientIP.startsWith("::ffff:") ? clientIP.slice(7) : clientIP
);
const isIPv4Mapped = clientIP.startsWith("::ffff:");
const displayIP = isIPv4Mapped ? clientIP.slice(7) : clientIP;
const isPrivate = family === "IPv4" ? isPrivateIPv4(displayIP) : false;
console.log(`\n[Connection]`);
console.log(` Raw address: ${clientIP}`);
console.log(` Display IP: ${displayIP}`);
console.log(` Protocol: ${family}${isIPv4Mapped ? " (via IPv4-mapped IPv6)" : ""}`);
if (family === "IPv4") {
console.log(` Scope: ${isPrivate ? "Private (RFC 1918)" : "Public"}`);
}
socket.write(`Protocol: ${family} | IP: ${displayIP}\n`);
socket.end();
});
server.listen(port, "::", () => {
console.log(`Server on port ${port} — accepting both IPv4 and IPv6`);
});
}
// === Run ===
(async () => {
await resolveAll("google.com");
await resolveAll("cloudflare.com");
console.log("\n--- Address detection ---");
const tests = ["192.168.1.1", "10.0.0.1", "8.8.8.8", "2001:db8::1", "::1", "fe80::1"];
for (const addr of tests) {
const family = detectAddressFamily(addr);
const private_ = family === "IPv4" ? `| Private: ${isPrivateIPv4(addr)}` : "";
console.log(` ${addr.padEnd(20)} → ${family} ${private_}`);
}
startServer(3000);
})();
What this shows:
dns.resolve4anddns.resolve6let you explicitly query A and AAAA recordsnet.isIPv4/net.isIPv6detect address family at runtime- IPv4 connections arriving on an IPv6 socket appear as
::ffff:x.x.x.x— strip the prefix for display - Binding to
::accepts both protocols on the same port
Common Mistakes
Mistake 1 — Thinking IPv6 removes the need for firewalls
IPv6 eliminates the need for NAT as an address-conservation mechanism. It does not eliminate the need for firewalls. With NAT, devices behind a router are unreachable from the internet by default — NAT provides accidental security through obscurity. With IPv6, every device is publicly reachable, which makes a proper stateful firewall more important, not less. Disable inbound connections at the firewall — do not rely on NAT for security.
Mistake 2 — Writing IPv6 address literals without brackets in application configs
A bare IPv6 address 2001:db8::1 in a URL or config looks like multiple fields separated by colons. In URLs: http://[2001:db8::1]:8080. In nginx upstream configs, some tools, and connection strings, the syntax for IPv6 varies — always check the documentation for your specific tool.
Mistake 3 — Assuming removal of the IPv4 header checksum means IPv6 is less reliable
The IPv4 header checksum covers only the header, not the payload. It was recalculated at every router hop (because TTL changes). IPv6 removed it because the checksum was already redundant: Layer 2 (Ethernet FCS) catches transmission errors, and Layer 4 (TCP/UDP checksum) validates the payload. Removing the header checksum makes IPv6 packet forwarding faster in routers — it is a deliberate performance optimization, not a reliability tradeoff.
Interview Questions
Q: What are the main differences between IPv4 and IPv6?
The core differences: IPv4 uses 32-bit addresses (~4.3 billion), IPv6 uses 128-bit addresses (~340 undecillion). IPv6 has a fixed 40-byte header with no checksum (IPv4's header is variable 20–60 bytes with a checksum recalculated at every hop). IPv4 requires NAT because of address exhaustion; IPv6 gives every device a globally unique address so NAT is unnecessary. IPv4 has broadcast; IPv6 replaced it with multicast. IPv6 mandates IPSec; IPv4 makes it optional. IPv6 supports SLAAC (stateless address autoconfiguration without DHCP).
Q: Why does IPv6 not have a checksum in its header?
Three reasons. First, the checksum is redundant: Layer 2 (Ethernet FCS) already catches transmission errors, and Layer 4 (TCP/UDP) checksums validate the payload. Second, the only IPv6 header field that changes in transit is Hop Limit (equivalent to TTL) — and it is not worth recalculating a checksum at every hop just for this one field. Third, removing the checksum speeds up packet processing on routers since they no longer need to compute it per hop. Reliability is maintained by the layers above and below.
Q: Why is IPv6 adoption slow despite IPv4 being exhausted?
NAT extended IPv4's practical lifespan by allowing many private addresses to share one public address. The transition requires dual stack operation (running both protocols simultaneously), which doubles operational complexity. Network equipment, operating systems, applications, and ISP infrastructure all need updating. There is no forced cutoff date for IPv4, so the urgency is diffuse. Legacy applications hardcode IPv4 assumptions. The economic incentive for migration is weak until a critical mass of peers are on IPv6.
Q: As a developer, do you need to worry about IPv6 today?
Yes, in two areas. First, bind your servers to :: (the IPv6 wildcard) instead of 0.0.0.0 — on most systems, this also accepts IPv4 connections via IPv4-mapped addresses. Second, make sure your DNS queries and hostname resolution handle AAAA records — do not assume DNS always returns an IPv4 address. In cloud deployments, your VPC may assign IPv6 addresses. Kubernetes dual stack clusters expose services on both protocols. If you hard-code IPv4 strings in config, you will break in an IPv6-only environment.
Quick Reference — Cheat Sheet
| Attribute | IPv4 | IPv6 |
|---|---|---|
| Bit size | 32 | 128 |
| Addresses | ~4.3 billion | ~340 undecillion |
| Notation | Dotted decimal | Hex colon |
| Header size | 20–60 bytes (variable) | 40 bytes (fixed) |
| Header checksum | Yes | No |
| Fragmentation | Routers + senders | Senders only |
| Broadcast | Yes | No (multicast instead) |
| NAT | Required | Not needed |
| IPSec | Optional | Mandatory (spec) |
| DHCP | Required for auto config | Optional (SLAAC available) |
| Loopback | 127.0.0.1 | ::1 |
| Private range | RFC 1918 | Unique Local (fc00::/7) |
| DNS record | A | AAAA |
| URL format | http://1.2.3.4:80 | http://[2001:db8::1]:80 |
| Wildcard bind | 0.0.0.0 | :: |
| Adoption (2025) | ~100% | ~40–45% of traffic |
Previous: Lesson 3.2 — IPv6 — The Future of Addressing → Next: Lesson 3.4 — Subnetting & CIDR Basics →
This is Lesson 3.3 of the Networking Interview Prep Course — 8 chapters, 32 lessons.