REST vs gRPC vs WebSockets
Three ways services and browsers talk to each other, how each works, what it costs, and how to choose. Includes the WebSocket handshake computed by hand and a byte count of JSON versus protobuf.
REST sends stateless request-response messages over HTTP, usually as JSON, and suits public APIs. gRPC uses HTTP/2 and Protocol Buffers for compact, typed and streaming calls between services. WebSockets keep one connection open so either side can send at any time. Interviewers expect the first question: does the server need to push data unprompted?
REST sends request-response messages over HTTP, usually as JSON, and fits public APIs. gRPC uses HTTP/2 and Protocol Buffers for compact, typed, streaming calls and fits service-to-service traffic. WebSockets keep one connection open so either side can send at any time, which fits chat, live feeds and games.
- A REST API is stateless: each request carries everything the server needs, and the server keeps no client session between calls.
- A record of id, name and active flag took 40 bytes as compact JSON and 11 bytes in the Protocol Buffers wire format used by gRPC.
- gRPC over HTTP/2 supports four call types: unary, server streaming, client streaming and bidirectional streaming.
- Browsers cannot call gRPC directly, because browser APIs do not expose the HTTP/2 framing it needs, so gRPC-Web with a proxy is used.
- A WebSocket starts as an HTTP/1.1 request with Upgrade: websocket, and the server switches protocols with a 101 response and a SHA-1 based Sec-WebSocket-Accept value.
- When only the server needs to push updates, Server-Sent Events over plain HTTP are simpler than WebSockets.
01Three different shapes of conversation
REST and gRPC are both request-response: the client asks, the server answers. WebSockets are different: after setup, the connection stays open and both sides can send messages whenever they like.
The question to ask first is whether the server ever needs to push data to the client without being asked. If not, request-response is enough and you choose between REST and gRPC. If yes, you want a streaming or push mechanism.
02REST: resources over HTTP
A REST API models data as resources with URLs: GET /users/42 reads a user, POST /users creates one, PUT or PATCH updates, DELETE removes. It is stateless, meaning every request carries what the server needs and the server keeps no session between calls. That makes it easy to scale by adding servers.
Payloads are usually JSON, which is readable, works in every language and every browser, and is easy to debug with curl. HTTP gives REST caching, status codes and tooling for free.
The costs: JSON is verbose, the contract is informal unless you add OpenAPI, and fetching related data can take several calls (or over-fetching, where the response includes fields you do not need).
03gRPC: typed calls over HTTP/2
gRPC, created at Google, defines the API in a .proto file: the messages and the methods. Code generators produce typed clients and servers for many languages, so calling a remote method looks like calling a local function, and the compiler catches mismatches.
It sends Protocol Buffers over HTTP/2. Protobuf is a compact binary format. Take this record:
import json
msg = {"id": 12345, "name": "Asha", "active": True}
print(len(json.dumps(msg, separators=(',', ':')))) # 40 bytes as JSONEncoded by hand following the protobuf wire format (field number and type tag, then the value), the same data is 11 bytes: 08 b9 60 12 04 41 73 68 61 18 01. Smaller messages and no text parsing cut bandwidth and CPU.
HTTP/2 gives gRPC multiplexing over one connection and four call types: unary, server streaming, client streaming and bidirectional streaming. The trade-offs are that browsers cannot call gRPC directly (a proxy layer called gRPC-Web is needed), the binary payload is harder to inspect by eye, and every consumer needs the generated code.
04WebSockets: a persistent two-way channel
A WebSocket begins as a normal HTTP request with Upgrade: websocket and a random Sec-WebSocket-Key. The server replies 101 Switching Protocols with Sec-WebSocket-Accept, computed by appending a fixed GUID to the key, taking SHA-1 and base64-encoding it. This proves the server understood the protocol:
import base64, hashlib
key = 'dGhlIHNhbXBsZSBub25jZQ==' # example from RFC 6455
guid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
print(base64.b64encode(hashlib.sha1((key + guid).encode()).digest()).decode())
# s3pPLMBiTxaQ9kYGzzhZRbK+xOo=That output is exactly the value given in the RFC. After the handshake the same TCP connection carries WebSocket frames in both directions, with very little overhead per message.
It suits chat, live scores, collaborative editing and multiplayer games. The costs are operational. Connections are long-lived and stateful, so each open socket uses server memory, load balancers must support them, and you must handle reconnection, heartbeats and backpressure yourself. If only the server needs to push, Server-Sent Events over plain HTTP are simpler.
05Choosing between them
Use REST for public or partner APIs, browser-facing endpoints and anything where being easy to try with curl matters. It is the default for a reason.
Use gRPC between internal services where you control both ends, performance matters and you want strict contracts and streaming. Many companies expose REST at the edge and use gRPC inside.
Use WebSockets when messages must flow both ways at any moment with low delay. Use Server-Sent Events when only the server pushes. Long polling, where the client repeatedly asks and the server holds the request open, is a fallback that works almost everywhere.
These can be mixed. A page might load data over REST, then open a WebSocket for live updates.
06Common interview questions
Q: What does "stateless" mean in REST?
A: Each request contains all the information needed to process it. The server stores no client session between requests, so any server can handle any request.
Q: PUT versus PATCH?
A: PUT replaces the whole resource and is idempotent. PATCH applies a partial update. A repeated PATCH may or may not be idempotent depending on the operation.
Q: Why is gRPC faster than REST with JSON?
A: Compact binary messages, no text parsing, HTTP/2 multiplexing and header compression.
Q: Why can't browsers call gRPC directly?
A: Browser APIs do not expose the low-level HTTP/2 framing gRPC needs, so gRPC-Web with a proxy is used.
Q: How does a WebSocket start?
A: With an HTTP/1.1 Upgrade request. A 101 response switches the connection to the WebSocket protocol.
Q: How would you scale WebSockets?
A: Spread connections across servers behind a load balancer that supports them, and use a shared message bus such as Redis pub/sub so a message sent to one server reaches clients connected to others.