Part 13 — The return trip and the goodbye
The response goes back down and up again
The pod writes 201 Created + JSON. The data goes down the pod's stack (L7 →
L1), crosses the VPC, goes up the ALB's stack to L7 (the ALB reads the
response, may compress it, logs it), then down again into your TLS
connection. It crosses the Internet (routers handle only L1–L3), and the home
router reverses the NAT using its table (203.0.113.7:61001 →
192.168.1.23:54012). The laptop's stack takes it up from L1 to L7, and
JavaScript's await resolves.
Two details that surprise people:
- The return path may differ from the forward path. BGP routing is per-direction. Your traceroute shows only your direction.
- The NAT table entry is the only reason the reply finds you. If it had expired (an idle connection), the reply would be dropped and you'd see a timeout.
Ending the conversation
Nothing closes after your click. That's on purpose. The browser keeps the HTTP/2 connection open for the next click. Eventually:
After ~minutes idle: browser or ALB sends HTTP/2 GOAWAY (L7/L5 says "no more streams")
TLS close_notify alert (L6 says "end of encrypted data")
TCP FIN → ACK, FIN → ACK (L4 graceful close)
closer holds TIME_WAIT for 60 s (L4 hygiene)
NAT mapping expires in the home router (L3 state cleaned up)
ARP entry for gateway stays (refreshed) (L2)
Wi-Fi stays associated (L1/L2)
Graceful shutdown on deploys depends on getting this sequence right: stop
accepting new connections, send GOAWAY / Connection: close, finish in-flight
requests, then exit. Kubernetes adds a twist: removing a pod from load
balancer targets is asynchronous with sending it SIGTERM, so a pod must keep
serving for a few seconds after SIGTERM (a preStop sleep) or users get 502s
on every deploy.
Go deeper in the series
- Graceful shutdown, measured: a draining backend lost 0 of 300 requests
and
kill -9lost 24 (TCP/IP Chapter 57). - Shutdown in Kubernetes, with the
preStopsleep this section describes: Linux guide, Chapter 82.