How clients and servers talk
REST, GraphQL, gRPC, WebSockets, SSE, webhooks and queues: how each works, what breaks in production, how to fix it, and how to choose.
Most web incidents that look like "the API is flaky" are really a mismatch between a communication style and the job it was given: a request/response API stretched to do real-time work, a WebSocket with no resume, timeouts that grow instead of shrink. Read the parts in order the first time; later, jump straight to the failure you are seeing.
PART 1
How a request travels
Every style below rides on the same path. Knowing where time and failure go makes the rest easier to reason about.
- How it worksThe life of an HTTPS requestDNS, TCP, TLS and HTTP versions: where latency comes from before your code runs.Backend · 11 min
- How it worksHTTP caching: Cache-Control, validators and CDNsThe cheapest request is the one never sent; REST gets this for free, other styles must rebuild it.Backend · 14 min
PART 2
Request and response
The client asks, the server answers. The styles differ in who shapes the response and how tightly both sides are coupled.
- How it worksREST, GraphQL, gRPC, tRPC and webhooks: choosing an API styleThe overview: REST, GraphQL, gRPC and tRPC side by side.Backend · 14 min
- How it worksREST API design that clients can rely onREST done well: status codes clients can act on, idempotency, conditional updates, pagination and versioning.Backend · 18 min
- How it worksGraphQL in depth: schema, execution, caching and securityClient-shaped queries, and the bill that comes with them: N+1, caching, cost limits and partial errors.Backend · 18 min
- How it worksgRPC in depth: protobuf contracts, deadlines, streaming and load balancingTyped contracts and streaming between services; deadlines, schema evolution and HTTP/2 load balancing.Backend · 18 min
- How it worksAPI gateways, BFFs and service meshesWhere aggregation, auth and protocol translation live, and how that layer becomes a bottleneck.Architecture · 14 min
PART 3
Pushing data to clients
When the server has news before the client asks: polling, Server-Sent Events, WebSockets, and what changes when thousands of clients stay connected.
- How it worksPolling, SSE, WebSockets, push and webhooks: choosing a channelThe overview: polling, long polling, SSE, WebSockets, WebTransport and push compared.System design · 14 min
- How it worksServer-Sent Events in productionOne-way streaming over plain HTTP, the usual choice for notifications and LLM token streams.System design · 14 min
- How it worksWebSockets, from Upgrade to close frameThe two-way channel: the upgrade handshake, frames, heartbeats and close codes.System design · 12 min
- How it worksRunning WebSockets and SSE for many usersFan-out across servers, backplanes, slow consumers, deploys and when to buy instead of build.System design · 16 min
PART 4
Server to server and asynchronous
When nobody should wait: queues, events and webhooks trade immediacy for resilience.
- How it worksHow message brokers actually deliverDelivery guarantees, acks and redelivery: why every consumer must be idempotent.System design · 12 min
- How it worksEvent-driven architecture: events, sagas, outbox and read modelsEvents vs commands, outbox, sagas and how UIs cope with eventual consistency.Architecture · 16 min
- Symptom guideWebhooks arrive twice, late, or out of orderWebhooks are at-least-once and unordered; design the receiver for it.Backend · 7 min
PART 5
Choosing a style
With the mechanisms in mind, decide from the questions that matter: who initiates, how fresh, who consumes, what must survive failure.
PART 6
When HTTP APIs break
The failure modes that show up in request/response systems, whatever the style.
- Symptom guideRequests fail with 504 while the server keeps working after the client gave upTimeouts must shrink inward, or work keeps running after everyone gave up.System design · 9 min
- Symptom guideA brief blip turns into a long outageRetries at every layer turn a blip into an outage.System design · 9 min
- Symptom guideA request that does minutes of work times out, then runs twiceMinutes of work do not belong in one HTTP request.Backend · 8 min
- Symptom guideLarge requests or messages fail at some hop you didn't know had a limitEvery hop has a size limit, and the smallest one wins.Backend · 8 min
- Symptom guideA mobile screen makes a dozen API calls and loads slowly on cellularTwelve calls per screen is slow on any network; measure, then aggregate.Frontend · 8 min
- Symptom guideSearch results show an older query's resultsResponses arrive in any order; the UI must not trust arrival order.Frontend · 6 min
- Symptom guideA third-party API starts returning 429429 is a contract: honour Retry-After and budget your concurrency.Backend · 7 min
- Symptom guideCORS fails only in production or on preflightBrowser-only failures that never show up in curl.Frontend · 8 min
- Symptom guideA backend deploy breaks old app versionsClients you cannot redeploy pin your API's past.Backend · 8 min
- Symptom guideThe frontend breaks when the API response changesShared contracts and generated clients catch drift before users do.Architecture · 7 min
PART 7
When GraphQL and gRPC break
Style-specific failure modes worth knowing before you pick either.
- Symptom guideOne GraphQL request pins the databaseOne query can cost more than a thousand; limit by cost, not by request count.Security · 8 min
- Symptom guideThe CDN never caches GraphQL, and the client cache driftsPOST bodies defeat HTTP caches; persisted queries and cache ids bring caching back.Backend · 8 min
- Symptom guideThe page is empty but every dashboard is green200 OK with errors: dashboards stay green while users see empty screens.Backend · 7 min
- Symptom guideScaling out a gRPC service doesn't spread the loadLong-lived HTTP/2 connections pin traffic to whichever pod connected first.System design · 9 min
- Symptom guideAfter a proto change, old clients read the wrong valuesField numbers are the contract; renumbering silently corrupts old clients.Backend · 8 min
PART 8
When real-time breaks
Long-lived connections fail in ways request/response never does.
- Symptom guideWebSockets disconnect, duplicate, or lose eventsGaps, duplicates and stale state across reconnects.System design · 10 min
- Symptom guideLive connections drop after a minute of quietProxies and load balancers close quiet connections; heartbeat below their timeout.System design · 7 min
- Symptom guideReal-time messages reach only some users after scaling outAfter scaling out, a message reaches only users on the same instance.System design · 7 min
- Symptom guideEvery deploy causes a spike as all clients reconnect at onceEvery deploy disconnects everyone at once unless you drain and jitter.System design · 9 min
- Symptom guideA logged-out user keeps receiving live updatesAuth checked only at connect keeps revoked users subscribed.Security · 8 min
- Symptom guideStreamed events arrive in bursts or only at the endBuffering proxies and compression turn a stream into a batch.Frontend · 7 min
- Symptom guideThe app hangs once users open a few tabsHTTP/1.1's six connections per origin hang the app at the seventh tab.Frontend · 7 min
PART 9
Check yourself
Answer from memory first, then compare with the model answers.
Track reviewed