Lesson 1 · Communication and APIs

Choosing a Communication Pattern

How a system finds out about changes it didn't initiate.

HTTP is fundamentally a client-initiated protocol — a server can't just decide to send a client something. So whenever one system needs to know about a change happening in another, there are really only two shapes the answer can take: the client keeps asking, or the server is given a way to reach out first.

Every "how do I get real-time updates" design question — order status, chat messages, CI build results, payment confirmations — reduces to picking a point on that spectrum, and accepting the trade-off that comes with it.

The Big Picture

Pull vs. Push

In a pull model, the client owns the schedule — it asks repeatedly and accepts that most answers will be "nothing changed." In a push model, the server owns the timing — it calls the moment something happens, and the client's job is just to be reachable.

Neither is strictly better. Pull is simple and works behind any firewall; push is efficient but demands infrastructure on the receiving end. The right choice depends on who can be reached, and how fresh the data needs to be.

Two shapes for the same problem

Pull (Polling)
Client
Server
Client asks repeatedly, on its own clock
Push (Webhook)
Server
Client's endpoint
Server calls in, the instant something happens
A webhook is really just polling with the roles reversed — the "client" for that one HTTP call is the server that owns the event, and your endpoint is playing server.

The Spectrum

PatternsFive Ways to Learn About a Change

Each pattern trades implementation simplicity for freshness and efficiency. The right one depends on whether the receiver can accept inbound connections, how stale the data is allowed to get, and how much infrastructure you're willing to run.

Short PollingSimple

The client asks "anything new?" on a fixed interval, whether or not anything changed. Trivial to implement, but wastes requests when nothing's happened and caps freshness at the interval length.

Long PollingEfficient

The server holds the connection open until new data exists or a timeout elapses, then the client immediately reopens it. Cuts out empty round-trips, but each waiting client ties up a server connection.

WebhooksPush-based

The server calls a URL you registered the instant an event happens. No client-side loop at all — but the receiver must run public, always-on HTTP infrastructure, and any single delivery can be missed.

WebSocketsReal-time

A persistent connection stays open and either side can send the moment it needs to. Best latency available, but connection state must survive scaling and restarts.

SSEReal-time

A persistent one-way stream from server to client over plain HTTP. Simpler to deploy than WebSockets and passes through existing infrastructure more easily, but carries no client-to-server messages on the same channel.

Notice the progression: each step trades a simpler client for a more demanding one — until, with WebSockets, the client has to maintain a live connection just like the server does.

Reference

Every Option, Side by Side

Five patterns, and the whole comparison comes down to who opens the connection, and how long it stays open. Everything else — freshness, cost, what infrastructure you need — falls out of those two answers.

The shape of each exchange

API
Pull
Client
Server
One question, one answer
Example
Opening an order page. You see its status right then, nothing after.
Polling
Pull
Client
Server
Ask again, and again
Example
An order page asking “shipped yet?” every 5 seconds, over and over.
Webhook
Push
Server
Your URL
Server calls you
Example
A customer pays, and Stripe calls your server to say it went through.
WebSocket
Push
Client
Server
Both talk, stays open
Example
In Figma, you move your cursor, everyone sees it, and you see theirs.
SSE
Push
Server
Client
Server streams, client listens
Example
An AI answer appearing word by word. The server sends, you only read.
PatternFreshnessNeeds public endpointBest forMain cost
Request/Response APIOn demand onlyNoReading current state at the moment the client asksLearns nothing until it asks again
Short PollingBounded by the intervalNoLow-frequency updates, simple dashboardsMost requests come back empty
Long PollingNear real-timeNoNear-live updates when inbound calls are blockedTies up a server connection per waiting client
WebhooksImmediateYesServer-to-server integrations (payments, CI/CD, SaaS)A delivery can be missed or arrive twice
WebSocketsImmediateNoBidirectional real-time apps (chat, multiplayer, cursors)Connection state must survive scaling and restarts
SSEImmediateNoOne-way live feeds (notifications, live scores)No client-to-server channel; some proxies buffer streams
Webhooks are the only row that says Yes. That single column is what usually decides the design: a browser tab or a mobile app has no stable public URL, so webhooks are off the table before any other trade-off gets discussed.
Two questions get you to the answer. Can the receiver accept inbound connections? If no, webhooks are out. Does the client need to send messages back on the same channel? If yes, WebSockets; if no, SSE is simpler and survives proxies better.

Fault Tolerance

Webhook Delivery Isn't Guaranteed

A webhook call is a single, best-effort HTTP request from someone else's server to yours. If your endpoint is down, slow, or returns a non-2xx status, that event can be retried, delayed, or — eventually — dropped, depending on the sender's retry policy.

Because retries happen, the same event can also arrive more than once. Any receiver that isn't built to handle both of those failure modes will eventually miss an event or double-process one.

Treat webhooks as at-most-once, best-effort delivery. Anything that must not be lost — a payment, an order state change — needs a reconciliation path that doesn't depend on the webhook having fired.
That reconciliation path is usually just polling — a periodic call to the provider's API that lists recent events and repairs anything the webhook silently missed. Push for speed, pull for correctness.

Quiz Review

Check your understanding

Question 1 of 11

What's the core difference between polling and webhooks in terms of who initiates the exchange?

  • With polling, the client repeatedly asks the server "anything new?" on its own schedule. With webhooks, the server calls the client's endpoint the moment something happens — the client never has to ask.