Skip to main content

Protocols: TCP, HTTP, WebSocket

Summary
  • TCP is the foundation: a reliable, ordered stream of bytes. Everything else is layered on top.
  • HTTP is request/response messages on top of TCP. Used for ~everything on the web.
  • WebSocket starts as HTTP, then upgrades into a persistent, bidirectional message stream — still on TCP.
  • The protocol choice mostly determines conversation shape: one-shot vs streaming, server-can-push vs client-must-poll.

The protocol stack at a glance

Almost every protocol you care about runs on TCP. The few exceptions (DNS, video streaming, gaming) use UDP for speed at the cost of reliability.

TCP: the foundation

TCP (Transmission Control Protocol) gives you a reliable, ordered, bidirectional stream of bytes between two endpoints. That's the entire contract:

PropertyWhat TCP guarantees
ReliableIf you send bytes, they arrive — TCP retransmits lost packets.
OrderedBytes arrive in the order you sent them.
StreamNo message boundaries. If you write [hello] then [world], the receiver might read helloworld in one chunk, or he, llowor, ld in three.
BidirectionalBoth sides can write at any time.
Connection-orientedA 3-way handshake opens the connection before any data flows.

That last property — TCP is a byte stream, not a message stream — trips up a lot of developers. If you're writing a custom TCP protocol, you are responsible for framing: deciding where one logical message ends and the next begins. Common approaches: length-prefixed messages (4-byte length, then payload), or delimiter-based (read until newline).

Everything above TCP (HTTP, WebSocket, gRPC) is just a convention for framing and interpreting bytes on top of that stream.

HTTP: the universal request/response protocol

HTTP is text-based, stateless, and request/response shaped. Every interaction is one request from client + one response from server.

A raw HTTP/1.1 request actually looks like this on the wire — plain text, lines separated by \r\n:

GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/json

The blank line tells the server headers are done, body follows (no body here since it's a GET).

HTTP/1.1 vs HTTP/2 vs HTTP/3

VersionWhat changedWhy it matters
HTTP/1.1 (1997)Persistent connections (keep-alive), pipeliningOne TCP connection can serve many requests in sequence
HTTP/2 (2015)Multiplexing, binary frames, header compression, server pushMany requests in parallel on one connection — fixes head-of-line blocking
HTTP/3 (2022)Runs on QUIC (UDP), not TCPAvoids TCP head-of-line blocking entirely; faster handshakes

For most server code, the version is transparent — your framework speaks all three, and the client picks. You only think about it when tuning performance or choosing between gRPC (requires HTTP/2) and REST (works on any version).

HTTP is stateless

The server doesn't inherently remember anything between requests. Each GET /users/42 is independent — no concept of this is the same client as before.

Statefulness on top of HTTP is bolted on: cookies, session tokens, JWTs. The protocol itself doesn't care.

WebSocket: persistent, bidirectional, message-based

WebSocket starts as a regular HTTP request (so it can pass through firewalls and proxies), then upgrades the same TCP connection into a different protocol where either side can send messages at any time.

Key differences from HTTP:

HTTPWebSocket
Connection lifetimeOne request, then close (or pooled)One handshake, then persistent for the whole session
DirectionClient must initiate every exchangeEither side can send at any time
Message shapeHeaders + body, parsed each timeLightweight frames (a few bytes overhead)
StateStatelessStateful — server tracks every open connection
Best forREST APIs, traditional webChat, live dashboards, multiplayer games, collaborative editing

WebSocket is what you reach for when the server needs to push data to the client without being asked. Without WebSocket, the only HTTP-based alternative is polling (any new messages? every 2 seconds), which is wasteful and laggy.

Other protocols worth knowing about

gRPC

gRPC is built on HTTP/2 and uses Protocol Buffers (a compact binary format) instead of JSON.

Why use itWhy not
Compact wire format (smaller than JSON)Browsers can't speak it natively (need gRPC-Web bridge)
Strongly typed contracts (.proto files)Tooling adds complexity
Bidirectional streaming built inLess debuggable than HTTP (binary, not text)
Code generation for many languagesOverkill for simple internal APIs

gRPC's sweet spot: service-to-service communication inside a backend, where you control both ends and want type safety + performance.

Server-Sent Events (SSE)

A simpler alternative to WebSocket when you only need server → client push (no client → server messages on the same connection). It's just HTTP with a long-lived response and a specific content type. Used by stock tickers, log streamers, server-side AI streaming, etc.

MQTT

A lightweight pub/sub protocol on TCP. Designed for IoT devices on flaky networks with tiny resource budgets. Has built-in topics, QoS levels, and last-will messages.

Custom binary protocols

When you control both endpoints and need extreme efficiency (think: GPS trackers, financial market data), you often define your own framing on top of raw TCP. This is what the TCP server doc is about.

Picking the right protocol

Quick comparison table:

ProtocolPersistent?Bidirectional?FormatTypical use
HTTP/1.1PooledNo (client initiates)TextREST APIs, web pages
HTTP/2Yes (multiplexed)No (still req/resp)BinarySame as HTTP/1.1, faster
HTTP/3Yes (over QUIC/UDP)NoBinarySame again, faster on flaky networks
WebSocketYesYesFrames (text or binary)Chat, real-time UI
gRPCYesYes (streaming variants)Protobuf (binary)Backend microservices
SSEYesOne-way (server → client)Text (HTTP)Live feeds, log streaming
MQTTYesYes (via broker)Binary, tinyIoT devices
Raw TCPYesYesWhatever you defineCustom binary protocols

Common confusions

Is HTTPS a different protocol? No. HTTPS is just HTTP with TLS encryption added underneath. The HTTP semantics are identical. The TLS layer sits between HTTP and TCP.

Why is WebSocket still in HTTP's family then? Because the handshake is an HTTP request. After the handshake, the protocol switches — but reusing HTTP for the upgrade is what lets WebSocket pass through firewalls, proxies, and load balancers that only understand HTTP.

Is gRPC just better HTTP? Not exactly. gRPC is opinionated about type contracts and only works with HTTP/2. If you need browser support or schema-less flexibility, REST over HTTP is still the default.

My TCP server keeps getting partial messages — is that a bug? No, that's the byte-stream property doing its job. You need to design a framing scheme (length-prefixed or delimited) so your code knows where messages end.

Should I write a custom protocol on raw TCP? Rarely. Existing protocols (HTTP, WebSocket, gRPC, MQTT) cover most needs. Custom protocols make sense for very specific cases: hardware devices that can't speak HTTP, ultra-low-latency trading, or proprietary integrations.

Where this lands in the series

Now that you know what kinds of conversations exist, you can read the next doc and map each conversation shape to a server type:

  • HTTP → web server
  • WebSocket → WebSocket server (often on top of a web server)
  • Raw TCP → TCP server (for IoT, hardware, custom)
  • gRPC → gRPC server (HTTP/2 under the hood)

← Previous 4. Blocking vs Non-Blocking I/O Next → 6. Server Types & When to Use Each