Asynchronous vs Synchronous
December 26, 2023
Overview
From Computer Science to the Real World
Asynchronously and synchronously are the two ways that nodes in a system communicate with each other. There are other paradigms of communications (e.g. polling or streaming), but they can all be categorized as one of these two (or both). A node can be:
- a component within an application
- a container (built on Docker, for example)
- a virtual machine
- a machine (a computer)
However, these two methods of communication extend beyond Computer Science. They're the only two ways that anything or anyone can communicate. When you interrupt someone to speak with them directly, you're practicing synchronous communication. They might be busy, so you may need to wait for them to become free (as would happen if you call someone on the phone, and you wait for them to pick up). This scenario occurs between all the types of nodes in computer science mentioned above, and it's called blocking (the calling node is blocked and waiting).
For most of human history, the only forms of asynchronous communication were: letter mail, telegrams, carrier pigeons (or other animal), or written notes. The digital age changed this. Synchronous communication is still vital for immediate and intimate personal interactions, but asynchronous communication allows for greater overall bandwidth by allowing more information to be exchanged over time, without the need for simultaneous presence.
Categorization
Providing an exhaustive list of communication paradigms is impossible because the list is constantly evolving. To provide a sense of categorization, below are some examples:
Request / Response
Async or Sync: Use Case Dependant
The communication is initiated by the caller, and it is kept open until the callee responds. The connection is inherently synchronous if TCP is the underlying transport protocol (as is common). If there is only one request, then the request is also considered to be handled synchronously. If there are multiple requests, they can be completed concurrently and asynchronously if the appropriate library is used (such as Python's asyncio). Looking even closer, each of the multiple asynchronous requests in the high-level language are likely handled synchronously by the individual OS threads responsible for handling the I/O operation. Once all the low-level OS-thread requests have completed their request/response cycles, then the high-level request/response cycle of all the individual awaited requests are also complete.
Message Queues
Async or Sync: Both
Producers and Consumers are decoupled through the use of an intermediary message broker (responsible for managing the queue), which makes the high-level communication asynchronous. However, the direct communication with the message broker needs to be synchronous to guarantee message delivery.
Publish / Subscribe
Async or Sync: Use Case Dependant
This design pattern typically describes the high-level, asynchronous communication between Producers and Consumers, which are often decoupled through an intermediary message broker. This is not always the case and there is no reason why Consumers cannot be subscribed to individual Producers directly. Furthermore, if they were communicating through a network, the communication would need to be synchronous to guarantee receipt.
Polling
Async or Sync: Synchronous
Polling typically uses Request / Response for each attempt at fetching information. There is even a concept known as long-polling where the callee holds onto and keeps the connection open until it has something to respond.
Streaming
Async or Sync: Both
At a high level, both the client and server need to be simultaneously present for the communication to take place. However, at a low level, each packet of information is typically UDP and is sent without waiting for a response (some packets can be lost).
Updated: 2023-12-30. To be updated in the new year with diagrams and a deeper dive, especially around use cases.