Distributed Realities & Asynchronous APIs

Breaking the synchronous request/response cycle using Webhooks, SSE, WebSockets, and event-driven architecture.

v1.0.0 Updated: September 09, 2026

The Synchronous Bottleneck

Standard REST APIs operate on a synchronous request/response cycle. A client opens a TCP connection, sends an HTTP request, and waits (blocks) until the server processes the logic and returns a response.

This model collapses when dealing with long-running processes, such as rendering a 4K video, generating a complex financial report, or waiting for a human to approve a workflow. If a server takes 5 minutes to process a request, the HTTP connection will inevitably time out, dropping the response into a black hole.

The naive approach is Polling: the client constantly sends GET requests every few seconds asking, “Are you done yet?” This wastes immense network bandwidth, burns CPU cycles on both ends, and scales horribly. Professional engineering requires asynchronous paradigms.

Asynchronous Paradigms

To handle long-running state transitions or real-time data, engineers invert the communication model.

1. Webhooks (Server-to-Server)

A Webhook is essentially a “Reverse API.” Instead of the client polling the server, the client provides the server with a callback URL. The server immediately returns a 202 Accepted status code (acknowledging the request without blocking), closes the connection, and begins background processing. Once the job is finished, the server sends an HTTP POST request to the client’s URL with the payload.

2. Server-Sent Events / SSE (Unidirectional Streaming)

When a client (like a web browser) needs real-time updates (e.g., a live stock ticker or sports scores), Webhooks cannot be used because browsers do not have publicly reachable IP addresses. SSE allows the client to open a single, long-lived HTTP connection. The server keeps this connection open and pushes a continuous stream of text-based events to the client.

3. WebSockets (Bidirectional Full-Duplex)

While SSE is one-way (server to client), WebSockets provide a persistent, two-way communication channel over a single TCP connection. This is required for highly interactive, low-latency systems like multiplayer games, collaborative text editing, or live chat applications.

sequenceDiagram participant Client participant Server Note over Client, Server: The Inefficient Polling Model Client->>Server: POST /reports (Generate) Server-->>Client: 202 Accepted (Status: Pending) loop Every 5 Seconds Client->>Server: GET /reports/123/status Server-->>Client: 200 OK (Status: Pending) end Client->>Server: GET /reports/123/status Server-->>Client: 200 OK (Status: Complete, Data: [...]) Note over Client, Server: The Efficient Webhook Model Client->>Server: POST /reports (Include Callback URL) Server-->>Client: 202 Accepted Note over Server: Background Processing (5 minutes) Server->>Client: POST /client-callback (Data: [...]) Client-->>Server: 200 OK

Microservice Reality: Orchestration vs. Choreography

When scaling to multiple APIs communicating with one another, teams must choose how to manage complex workflows (e.g., placing an order requires checking inventory, billing a card, and scheduling shipping).

  • Orchestration (Command-Driven): A central “Controller” API explicitly commands other APIs what to do via synchronous HTTP calls. It is easier to trace but creates a massive single point of failure and high latency.
  • Choreography (Event-Driven): No central controller exists. When an order is placed, the Order API simply publishes an “OrderCreated” event to an asynchronous message broker (like Apache Kafka or RabbitMQ). The Inventory and Billing APIs independently subscribe to this event and react to it. This provides incredible scalability and fault tolerance, but makes tracing system state notoriously difficult.
💡
Architectural Note: In event-driven choreography, you must design your APIs to handle out-of-order delivery. Due to network latency, the Shipping API might receive the “OrderUpdated” event before it receives the “OrderCreated” event.

Test Your Understanding

Q:You are designing an API for a machine learning service. A client uploads an image, and your backend takes roughly 45 seconds to analyze it. The client is a mobile app. Which asynchronous pattern should you use, and why? Reveal ▾
You cannot use a Webhook, because a mobile phone does not have a static, public IP address or an active HTTP server to receive the callback. The optimal solution is to return a 202 Accepted with a Job ID upon upload. Then, the mobile app opens a Server-Sent Events (SSE) connection or a WebSocket connection, listening for an event corresponding to that Job ID. Alternatively, if battery conservation is paramount, the app can use native mobile push notifications (APNs/FCM) as a specialized substitute for Webhooks.

Further Exploration

← Previous
Security, Gateways & Intermediaries