HTTP, TCP, UDP, REST and RPC
How two machines talk, and which style to pick between your own services.
What problem does each protocol solve?
Everything in a distributed system is machines sending each other messages. A few choices decide what those messages cost, and what happens when one goes missing.
You do not need the inner workings of each protocol. You need to know what each one promises, what it costs, and when to reach for it.
What each protocol costs you
Every concept in here states a cost. A technique with no price is a technique you have not understood yet — and naming the cost out loud is most of what separates a senior answer from a junior one.
When to reach for each protocol, and when not to
Use it when
- TCP: anything where losing a message is not acceptable, which is almost everything.
- UDP: real-time video, voice, games, metrics. Anywhere a late message is worthless, and losing one beats delaying the rest.
- REST over HTTP: public APIs, anything crossing between companies, anything a CDN should cache.
- RPC (usually gRPC): high-volume calls between your own services, where you control both ends.
Do not, when
- Do not use UDP because it sounds faster. If you then rebuild delivery and ordering on top, you have written a worse TCP.
- Do not put gRPC on a public API. REST over HTTP is what the rest of the world can use and cache.
How each protocol actually works
- —Every byte arrives, in order, or the connection fails loudly.
- —Costs a handshake to set up, and resends anything lost.
- —A lost packet holds up everything behind it while it is resent.
- —Right for: APIs, databases, file transfer — nearly everything.
- —Send and forget. No handshake, no retries, no ordering.
- —A lost packet is simply gone, and the next one still arrives on time.
- —You handle loss yourself, or you design so that loss does not matter.
- —Right for: live video and voice, games, high-volume metrics.
The layers, briefly, so the words stop being mysterious. IP gets a packet to a machine. TCP sits on top and turns unreliable packets into a reliable, ordered stream. HTTP sits on top of that and defines requests and responses. TLS sits between TCP and HTTP and adds encryption, which is what the S in HTTPS means.
REST is a style, not a technology. Resources have URLs, and HTTP verbs act on them: GET reads, POST creates, PUT replaces, DELETE removes. Its main advantages are that everything understands it, and that GET requests can be cached by browsers, proxies and CDNs. That is a large speed win you get for free.
RPC turns the model around. Instead of resources, you call a function on another machine as if it were local. gRPC is the common modern version. It uses a compact binary format instead of JSON, and HTTP/2 underneath, which usually makes it faster and gives you generated clients and streaming. The cost is that it is awkward to use from a browser, harder to debug because the binary payload is not human-readable, and not cacheable by the normal HTTP machinery.
The rule of thumb is worth saying out loud: REST at the edge, RPC inside. A public API where you do not control the caller and want caching: REST. High-volume calls between your own services where you control both ends: gRPC. And RPC has one leak worth naming. Making a remote call look like a local function call tempts people to forget it can fail, be slow, or happen twice. At scale, all three happen.
One design-level point matters more than the protocol choice: the number of calls usually costs you more than the format does. Twenty calls in a row at 20 ms each is 400 ms, whatever wire format you picked. Grouping calls and running them at the same time usually beats protocol tuning.
- Choosing UDP for speed, then rebuilding retries and ordering on top of it.
- Treating an RPC call like a local function. It can fail, hang, or run twice.
- Tuning the wire format when the real cost is making twenty calls one after another.
The each protocol follow-up an interviewer will ask
"Why would you use gRPC internally but REST at the edge?"
The two sides have different constraints. Inside, I control both ends, calls are high volume, and I care about the cost of each call. gRPC gives me a compact binary encoding instead of JSON, HTTP/2 so many calls share one connection, generated clients on both sides, and a schema that makes breaking changes show up at build time instead of in production. At the edge, none of that matters as much as reach and caching. Any client in the world can use REST over HTTP, browsers speak it natively, and GET responses can be cached by the CDN and the browser, which is a big win I would be throwing away. There is also a debugging argument: I can curl a REST endpoint and read the answer, which matters at three in the morning. The cost of running both is a translation layer at the boundary, usually the gateway, and I think that is worth it.
Your turn
Real-time video, such as a video call, usually uses UDP rather than TCP. Why is losing data better than waiting for it here?
Learn it from the source
This page gets you interview-ready. These take you to where the idea is actually specified or measured — read them when you want the real depth.
- RFC 9110 — HTTP Semantics ↗The current HTTP semantics specification. It replaces RFC 7231, which itself replaced the still widely cited RFC 2616.
- What is gRPC? ↗The official introduction, including when its authors think you should not use it.