intermediate 2 min answer

Where should the boundary between synchronous and asynchronous processing sit in an API platform, and what determines it?

syncasynclatencyacknowledgementtwiliodesign
Show the full answer Hide the answer

What determines it

What the caller needs to know before proceeding, and how long the work takes relative to their tolerance.

Synchronous when the caller needs the result to continue: validation, authorisation, an identifier they will use immediately. Anything that determines whether the request is accepted.

Asynchronous when the work is expensive, variable in duration, or dependent on external systems the caller should not wait for — delivery to a carrier, rendering, indexing, notification.

The API design that follows

Acknowledge synchronously; complete asynchronously. The request returns quickly with an identifier and a state, and the outcome is delivered later through polling or a webhook.

That gives the caller: immediate confirmation their request was accepted and durably recorded, a handle to enquire with, and no dependency on the platform's downstream latency.

The acknowledgement must be meaningful. It should mean the request is durably recorded and will be processed — which requires writing it transactionally before responding. An acknowledgement that means "we received the bytes" is a promise the platform cannot keep.

What must be true for the asynchronous half

  • Idempotency on submission, because a client that times out will retry and cannot know whether the first attempt succeeded.
  • A queryable state by the caller's identifier and by their idempotency key, so a client that exhausted its retries can determine what actually happened rather than guessing.
  • Delivery of the outcome with at-least-once semantics and a deduplication identifier, since exactly-once to a system you do not control is not achievable.
  • A durable record of every attempt, visible to the customer, which converts the largest category of support question into self-service.

The failure to avoid

Making something asynchronous that the caller needs synchronously, which adds a correlation problem and a waiting state without decoupling anything meaningful — and making something synchronous that depends on an external system's latency, which couples the caller's experience to a third party's worst day.

The boundary is a product decision about what the caller is promised, not a technical preference.