Client-Server Architecture
Overview
Client-server communication patterns define how a client and server exchange data over a connection: the classic request-response model, plus three techniques for pushing updates to the client - long polling, WebSockets, and server-sent events. The right pattern depends on how fresh the data must be and which side initiates messages.
Key Concepts
All of these patterns ride on the protocols covered in networking foundations.
- Request-response is the default: the client sends a request and the server replies once. The server cannot initiate; to get new data the client must ask again. It is simple, stateless, and ideal for reads and commands, but poor for real-time updates.
- Long polling simulates push over ordinary HTTP: the client makes a request and the server holds it open until data is available (or a timeout fires), then responds; the client immediately reissues the request. It delivers near-real-time updates without special protocols but wastes connections and adds latency per cycle.
- WebSockets upgrade a single HTTP connection into a persistent, full-duplex channel where either side can send at any time. This suits low-latency, bidirectional traffic like chat and multiplayer games, at the cost of holding stateful connections open on the server.
- Server-sent events (SSE) provide a one-way, server-to-client stream over a long-lived HTTP connection. They are lighter than WebSockets and auto-reconnect, but the client cannot push back on the same channel. They fit feeds, tickers, and notifications.
Comparison of communication patterns
| Pattern | Direction | Connection | Best for |
|---|---|---|---|
| Request-response | Client to server | New per request | Reads, commands |
| Long polling | Server to client (simulated) | Repeated, held open | Simple near-real-time |
| WebSockets | Bidirectional | One persistent | Chat, games, live collaboration |
| Server-sent events | Server to client | One persistent | Feeds, tickers, alerts |
Trade-offs
The progression trades simplicity for immediacy and connection cost. Request-response is simplest but cannot push. Long polling adds push semantics with zero new infrastructure but burns requests and adds latency. WebSockets give the richest real-time, two-way channel but require managing many stateful, long-lived connections, which are harder to load balance and scale. SSE is a lightweight middle ground when updates flow only one way. Choose the least powerful pattern that meets the freshness requirement.
Interview Tips
- Justify the transport by direction and freshness, not by popularity.
- Default to request-response; reach for a push transport only when the product needs live updates.
- Prefer SSE over WebSockets when traffic is one-way - it is cheaper to scale.
- Mention that persistent connections complicate routing and often need sticky sessions or a dedicated connection tier.
Summary
- Request-response is the stateless default but cannot push updates to clients.
- Long polling fakes push over HTTP at the cost of wasted requests and latency.
- WebSockets give full-duplex, low-latency, two-way communication with stateful connections.
- Server-sent events stream one-way server-to-client updates cheaply.
- Choose the least powerful pattern that satisfies the data-freshness requirement.