Make the right trade-off / CHAPTER 38
Polling, long polling, WebSockets, and webhooks
Select a concrete delivery mechanism and define authentication, connection cost, and missed-message recovery.
Builds on Polling, long polling, WebSockets, and server-sent events, Push versus pull architecture.
- Compare the waiting behavior of four mechanisms.
- Distinguish browser channels from server callbacks.
- Design cursors and idempotent webhook processing.
01Four mechanisms, different constraints
A support-chat client wants new messages, while a billing provider needs to notify a merchant server about a purchase. The delivery mechanism depends on who can keep a connection open and which direction messages travel.
- Polling: the client repeatedly asks; each short request returns promptly.
- Long polling: the server holds one request until an update or timeout, then the client asks again.
- WebSocket: after setup, one connection carries messages in both directions.
- Webhook: the merchant registers a server URL and the provider sends an HTTP request to it when an event occurs. That request is a callback.
A webhook normally contacts a server, not a sleeping browser. A WebSocket can carry chat in both directions, but does not save messages or replay them automatically. Long polling retains connection and request state while waiting, even when no body bytes are moving.
02Every mechanism needs a lifecycle
Give every delivery a clear saved-history rule. A cursor records the last stream position a receiver safely applied; it does not grant permission to read that stream.
Follow a chat client that applied messages through 50:
- The message service saves message
51before promising durable acceptance. It records enough identity to recognize a retry. - If the client has a socket, send
51. The client applies it and saves its progress before reporting that position. - The connection breaks. On reconnect, authenticate and request history after the client's last applied position. Receiving
51again must not create another visible message. - If WebSockets are unavailable, long poll using the same conversation and cursor rules. Changing transport must not change history order or duplicate handling.
- If history no longer reaches that cursor, return an explicit reset response. The client fetches a snapshot or available history; an empty response would falsely imply that nothing was missed.
| Mechanism | Useful situation | Work the application still owns |
|---|---|---|
| Polling | Infrequent changes tolerate interval delay. | Count empty reads and implement saved progress. |
| Long polling | Server updates are needed without a permanent two-way channel. | Manage waiting requests, timeouts and reconnection. |
| WebSocket | Active two-way chat justifies an open channel. | Handle heartbeats, finite buffers, permissions and replay. |
| Webhook | A server integration receives billing events. | Verify authenticity, save acceptance and handle repeats or reordering. |
Check proxy idle timeouts along the deployed path; a server's chosen timeout alone does not keep the connection alive.
03Worked example: support chat and billing events
Billing event E9 reports a completed purchase at purchase version 1. Event E10 reports a later refund at purchase version 2. Their event IDs recognize retries; the purchase versions, not the spelling of those IDs, identify which state is newer. Follow what the merchant stores:
- Verify the callback. Check the signature using the provider's documented key or secret and the original received bytes. Reformatting JSON before verification can change the signed data. Check timestamps and permitted redelivery rules too.
- Save
E9before accepting it. A received-event record uses a unique provider/event key and stores pending processing. IfE9is already present, return the existing acceptance instead of creating new work. - Process the purchase once. For a local access grant, one transaction locks both
E9's event record and its purchase record. It checks whether the event is already processed and compares the purchase version while that record remains protected from another callback. For a still-paid purchase, it saves the access grant, purchase version and processed-event state together. If version 2 already records a refund, it marks the old paid event processed without restoring access. A concurrent or later retry sees processed state and skips the repeated grant. - Handle a lost callback response. The provider may legitimately send
E9again. A valid signature proves origin, not uniqueness; the saved event identity supplies repeat recognition. - Handle
E10beforeE9. Use the same protected purchase-record update to save the refund’s version 2 and remove access under the merchant’s refund rule. A later version-1 paid event must not overwrite that state. If callbacks do not carry ordered purchase versions, fetch the purchase’s current status from the provider before deciding access; arrival order is not a substitute.
If processing calls another external system, its effect needs separate retry protection; the local processed flag cannot undo an external action.
For chat, limit each slow client's outgoing buffer. Temporary presence changes may be combined, but keep accepted text in history. Disconnect a stalled client and let it resume, rather than keeping unlimited bytes in memory or silently dropping messages.
Polling, long polling, WebSockets, and webhooks — decision flow
Follow the numbered arrows
- Saved events → Browser delivery APImake saved updates available
- Browser delivery API → Browser clientreturn messages after the saved position
- Browser client → Browser delivery APIask for updates or resume history
- Saved events → Webhook sendersave work to notify the subscriber
- Webhook sender → Merchant serversend the signed event and its ID
Trace the diagram in words
- Save chat history or received billing-event work before promising durable acceptance.
- Send through the authenticated browser channel or verify the registered server callback.
- After failure, use saved positions and event IDs to recover missing work and recognize repeats.
04Choose the simplest mechanism that meets the delay target
Select the simplest mechanism meeting the required delay and direction:
- Daily public scoreboard: polling may be sufficient.
- Active chat: WebSockets can avoid repeated setup, with history-based recovery still required.
- Server billing integration: signed callbacks fit naturally, with durable event acceptance and repeat checks.
- Large idle audience: count open connections and timeout state, not only messages/s.
Define exactly what a success response acknowledges: receipt in memory, saved responsibility or completed business processing. Replying before saving a callback can lose accepted work in a crash. Waiting through a long workflow can instead trigger provider retries and occupy connections.
Trace one delivery, disconnect, duplicate and history gap. Reliable behavior comes from those explicit application rules; no transport name provides them automatically.
DRAW. CALCULATE. EXPLAIN.
Recover chat and billing
20 minutes · guided practice
A chat client applied messages through 80 but disconnected while 81 was being sent. A merchant receives paid event E9 (purchase version 1) twice and refund event E10 (version 2) before E9. Specify recovery, acceptance and ordering behavior.
Compare the worked solution
- The chat client reconnects with identity and last-applied position
80. Fetch81from history when retained and recognize its ID if it was already applied. - If
80is older than retained history, tell the client to reset through a snapshot or available history rather than silently skipping messages. - Verify each billing callback and save its event ID with pending work before reporting durable acceptance. Repeated
E9finds the existing record. - Commit a local access grant and processed-event state together, or use the external provider's repeat-recognition mechanism for an external effect.
- Save the refund at purchase version 2. When
E9later presents paid version 1, record its processing without restoring access. If versions are unavailable, query the provider’s purchase status before changing access. Arrival order alone does not establish business order.
The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.
RETRIEVE BEFORE YOU REVEAL
Keep the important ideas.
Say the answer aloud, then turn the card over.
CARD 01How do the four mechanisms differ?
- Polling asks repeatedly.
- Long polling holds one request until update or timeout.
- WebSockets keep a two-way channel open.
- Webhooks call registered servers.
All still need application recovery rules.
CARD 02What makes chat reconnect safe?
- Authenticate and request history after the last applied position.
- Recognize repeated message IDs.
- If required history expired, fetch a snapshot or available history instead of silently skipping the gap.
CARD 03How does a webhook avoid repeating a local grant?
- Verify the callback.
- Save its unique event ID and pending work before accepting.
- Commit the grant and processed-event state together.
- A repeated event finds that saved record.
CHECK THE REASONING
Can you explain the choice?
Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.
CLOSE THE LOOP
Explain it without the page.
Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.