Opening

In the last video, we traced a single API call and saw that it takes around 500 milliseconds just to get a response back. But where exactly does all that time go? And more importantly — why? Today we are going to dig into the two protocols that carry almost all of your app's network traffic: TCP and HTTP. We will look at how TCP guarantees that your data arrives intact and in order, why the first request to any server is always the slowest, and how the evolution from HTTP/1.1 to HTTP/2 to HTTP/3 has been one long fight against latency. If you have ever wondered why mobile networking feels fundamentally different from Wi-Fi, this video will explain exactly why.

What TCP Actually Guarantees

TCP — Transmission Control Protocol — makes two big promises. First: every byte you send will arrive at the other end. None will be lost. Second: the bytes will arrive in the exact order you sent them. This might sound obvious, but it is not how the underlying network works at all. The internet is a packet-switched network. Your data gets chopped into small packets, and each packet might take a completely different route to reach the server. Some packets might arrive out of order. Some might get lost entirely — dropped by a congested router or corrupted in transit. TCP handles all of this for you. It detects lost packets and retransmits them. It reorders packets that arrive out of sequence. It gives you the illusion of a perfect, reliable pipe. But maintaining that illusion has a cost. And that cost is latency.

Sequence Numbers, ACKs, and Retransmission

Here is how TCP pulls off its magic. Every byte of data gets assigned a sequence number. When your phone sends a packet, it says "here are bytes 1 through 1400." When the server receives it, it sends back an acknowledgment — an ACK — saying "got it, I am ready for byte 1401." If the server does not send an ACK within a certain time, your phone assumes the packet was lost and retransmits it. This is elegant, but think about the timing. Your phone sends data. It waits for an ACK. If the round trip is 50 milliseconds, that is 50 milliseconds of waiting per packet. And if a packet is lost? Your phone has to wait for a timeout — typically a few hundred milliseconds — then retransmit, then wait for the ACK again. A single lost packet can add 200 to 500 milliseconds of delay. On mobile networks where packet loss rates can be 1 to 5 percent, this happens more than you would think.

TCP Slow Start: Why the First Request is Slowest

Here is something that surprises a lot of developers. TCP does not just blast data at full speed from the start. It has a mechanism called slow start, and it is exactly what it sounds like. When a new TCP connection is established, neither side knows how much bandwidth is available. If your phone immediately sent a megabyte of data, it might overwhelm some router along the way and cause massive packet loss. So TCP starts cautiously. It begins with a small congestion window — typically about 14 kilobytes. It sends that much data, waits for acknowledgments, and then doubles the window. Send 14 KB, get ACKs, send 28 KB, get ACKs, send 56 KB, and so on. This exponential growth means TCP ramps up to full speed fairly quickly — but "fairly quickly" still means several round trips. And on mobile, where each round trip is 50 to 100 milliseconds, that can add up to 200 to 400 milliseconds before TCP is running at full capacity. This is why the first large response from a server always feels slow. Your connection is literally warming up.

HTTP/1.1 and Head-of-Line Blocking

Now let us layer HTTP on top of TCP. HTTP/1.1 has been the workhorse of the web for over two decades. It is simple: one request, one response, over a TCP connection. But it has a fundamental limitation. On a single connection, requests are sequential. You send request one, wait for the response, then send request two. This means if request one is slow — maybe the server takes 500 milliseconds to process it — request two is stuck waiting. This is called head-of-line blocking. The slow request at the head of the line blocks everything behind it. Browsers worked around this by opening multiple TCP connections to the same server — typically six. But each one needs its own TCP handshake and TLS negotiation. And each one goes through slow start independently. So the workaround has its own costs. Your Android app using OkHttp faces the same issue — though OkHttp's connection pooling helps by keeping those connections warm.

HTTP/2: Multiplexing to the Rescue

HTTP/2 was designed to solve head-of-line blocking. The big idea is multiplexing — sending multiple requests and responses over a single TCP connection at the same time. Instead of requests being sequential, they are broken into small frames. Frames from different requests are interleaved on the wire. So while the server is still processing request one, it can already be sending the response for request two. This is a huge win. One TCP connection. One TLS handshake. One slow start ramp-up. But all your requests flowing in parallel. OkHttp automatically negotiates HTTP/2 when the server supports it. You do not need to change anything. And most modern API servers support it. But HTTP/2 has its own Achilles heel. Remember, it runs on TCP. And TCP guarantees in-order delivery. If a single TCP packet is lost, the entire TCP stream stalls while that packet is retransmitted. Even if the lost packet only contained data for request one, requests two and three are also blocked because TCP does not know about HTTP/2's multiplexing. This is TCP-level head-of-line blocking, and it is worse on lossy networks — like mobile.

HTTP/3 and QUIC: The UDP Revolution

This brings us to HTTP/3, which is built on a completely new transport protocol called QUIC. And here is the radical part — QUIC runs on UDP, not TCP. UDP is a bare-bones protocol. It does not guarantee delivery. It does not guarantee order. It just fires packets and hopes for the best. So why would you build a reliable protocol on unreliable UDP? Because QUIC implements its own reliability — but smarter than TCP. QUIC has independent streams. If a packet is lost on stream one, only stream one stalls. Streams two and three keep flowing. No more head-of-line blocking at the transport layer. QUIC also integrates TLS 1.3 directly into its handshake, so the connection setup takes just one round trip instead of the separate TCP plus TLS handshakes. On a mobile network with 50 millisecond round trips, that can save 100 to 150 milliseconds on every new connection. And QUIC handles IP address changes gracefully — critical for mobile, where your IP can change when you switch from Wi-Fi to cellular.

What OkHttp Does Under the Hood

OkHttp is remarkably sophisticated. Let me walk you through what it actually manages for you. First: connection pooling. It maintains a pool of open connections, indexed by server address. When you make a request, it checks the pool first. Second: protocol negotiation. During the TLS handshake, OkHttp uses ALPN — Application Layer Protocol Negotiation — to determine whether the server supports HTTP/2. If so, it upgrades automatically. Third: connection coalescing. If two different hostnames resolve to the same IP and share a wildcard TLS certificate, OkHttp can reuse a single HTTP/2 connection for both. Fourth: failed connection recovery. If a pooled connection turns out to be stale — the server closed it while it was idle — OkHttp catches the error and retries on a new connection transparently. All of this happens in OkHttp's interceptor chain, completely invisible to your Retrofit code. But knowing it is there helps you understand your app's networking behavior when you look at network traces.

Why Mobile Networks Are Special

Mobile networks are a different beast from Wi-Fi, and it is not just about speed. Three things make mobile networking fundamentally harder. First: latency. A typical Wi-Fi round trip is 5 to 15 milliseconds. On LTE, it is 30 to 70 milliseconds. On 3G, 100 to 300 milliseconds. Every handshake, every ACK, every retransmission is multiplied by that latency. Second: packet loss. Mobile networks have significantly higher packet loss than wired connections — 1 to 5 percent is common, and it spikes when signal is weak or when you are moving. Remember, a single lost TCP packet can stall your entire stream for hundreds of milliseconds. Third: IP address changes. When you walk from Wi-Fi to cellular, or when the cell tower hands you off, your IP address can change. TCP connections are identified by the source IP and port — if either changes, the connection is dead. OkHttp has to detect this and create a new connection from scratch. New DNS. New TCP handshake. New TLS negotiation. All of this means that network code that works beautifully on your office Wi-Fi might perform poorly for users on the subway. You have to test on real mobile networks.

A Practical Latency Budget

Let me give you a practical way to think about this. Every network operation in your app has a latency budget — the maximum time a user will wait before the experience feels broken. For interactive operations — a user taps a button and expects a result — you have about one second. For background operations — sync, prefetch, analytics — you have more time, but less than you think, because the user might close the app or lose connectivity. So here is how to think about budgeting. Your cold connection setup costs about 200 milliseconds — DNS, TCP, TLS. Server processing takes another 100 to 300 milliseconds. Download takes 50 to 200 milliseconds depending on payload size. Serialization takes 10 to 50 milliseconds. That leaves very little room for error in a one-second budget. If any single step goes wrong — a DNS cache miss, a packet loss during TLS, a slow database query — you blow through your budget. This is why connection pooling, HTTP/2, prefetching, and caching are not premature optimizations. They are essential architecture for mobile apps.

Recap and What is Next

Let us bring it all together. TCP gives you reliable, ordered delivery — but at the cost of head-of-line blocking, slow start, and sensitivity to packet loss. HTTP/1.1 layered on sequential requests. HTTP/2 added multiplexing but still suffered from TCP-level blocking. HTTP/3 and QUIC moved to UDP to solve that problem, with the added bonus of faster handshakes and graceful IP migration. OkHttp manages all of this for you — connection pooling, protocol negotiation, failed connection recovery — but understanding what it does helps you design better apps. And mobile networks amplify every problem — higher latency, more packet loss, changing IP addresses. In the next video, we are going to talk about what happens when all of this goes wrong — retries, backoff, and timeouts. Because on mobile, failure is not the exception. It is the norm. See you there.