Petya Petrova - Fotolia
Software architects and developers must understand the differences between synchronous vs. asynchronous communications and how they apply to program execution and systems design.
Let's start by exploring some scenarios that illustrate how these two communication approaches work. Then, we'll explore the details of synchronous and asynchronous communications, including their behavior in hardware, cloud and microservices.
Synchronous vs. asynchronous communication example
In synchronous communications, multiple parties continually listen for and act upon replies from each other. One way to visualize the concept of synchronous communications is to imagine a real-time online chat system designed for a retailer's customer support. The support specialist quickly exchanges messages with the customer to help them track an order, report a missing delivery or inquire about a certain product.
In this scenario, both the sender and receiver establish a communications session. Once the session is established, the two-way conversation takes place with no restrictions on who inputs information when. As one party types and sends a chat message, the party at the other end is present and actively waiting to receive and respond to your message. This is what defines synchronous communications.
In asynchronous communication, parties do not actively listen for messages. Building off the example above, imagine the customer uses an email support channel instead of the live chat. Asynchronous transmission occurs when the email is sent to the manufacturer's support department. The customer does not expect to receive a reply in real time. Rather, the email message arrives at the retailer, where the staff choose when to read or reply to the message.
Asynchronous communications typically incur a delay between when the sender initiates the message and when the recipient responds. The length of this delay depends on the communication medium. A similar example based on physical mail would likely take even longer in transit. The two parties of an asynchronous exchange do not work together in real time. In fact, either receiving end may be completely unaware of who exactly they are interacting with.
These two forms of data transmission can be easy to understand in terms of human communications, but it's significantly more difficult for architects and developers to apply them in software design. And while the basic principles guide the execution of program code, the amount of time it takes for these software-based communications to transmit can often be measured in milliseconds.
Synchronous vs. asynchronous execution
Applications generate messages in the form of calls to functions, services and APIs. The way that an architect designs these communications affects the application's performance, resource consumption and ability to execute tasks. Synchronous vs. asynchronous methods each have potential benefits and drawbacks, but the method you choose depends on an application's purpose.
When a software component communicates synchronously, it sits idle until it receives a call, response, value or other data transfer. For example, synchronous execution occurs during online shopping. A user decides to purchase a product, and the system generates a query to determine if inventory is available. The app waits for a response before starting the checkout process. This synchronous design prevents mismatches between inventory and sales.
Conversely, asynchronous communication allows code to continue to run after it has generated a call or response. Asynchronous communication is particularly valuable for reporting and alerts, such as a manufacturing application that monitors the temperature of an industrial furnace, continually transmits status updates and automatically sends alerts. This type of application should never stop and wait for responses before it moves on to the next action. Instead, the communication alone should trigger either personnel or another application to take action. For instance, the application might send asynchronous temperature updates throughout the day, but also set off a troubleshooting sequence whenever temperatures either exceed or drop below acceptable levels.
Performance considerations for reads and writes
In research first published in 1992 and updated in 2002, two researchers noted that clock skew -- a situation where linked digital components receive time indications at different intervals -- significantly impacts a synchronous system's performance. Clock skew can particularly cause problems in densely designed systems that host large numbers of components.
Clock skew is even more damaging in asynchronous communication, and it is a challenge to ensure that each module and constituent component's clock remains synchronized with the others. Read-and-write storage operations are likely to occur milliseconds apart. Without clock synchronization, I/O operations will occur in the wrong order.
Cloud data storage, especially cloud backup for on-premises systems, can put primary and backup data in different locations. Remote synchronous replication dictates that read-and-write operations occur in time with the primary and backup data storage locations.
Another challenge is the need to correlate multiple data streams that encompass both synchronous and asynchronous collection methods. This issue is especially present in data mining and streaming analytics.
Microservices design considerations
In most monolithic application architectures, statements about the system's behavior are relatively evident as part of the app design. However, when the underlying architecture is made up of distributed services, it is harder to track the flow of communication. A single task built on dispersed services likely involves multiple layers of communication.
Coherence around inter-service communication is one of the challenges in a distributed architecture like microservices. To deal with that challenge, learn the variations, complexities and possible approaches while conceptualizing the architecture.
Communications between services in a microservices architecture can be:
- decentralized and synchronous;
- choreographed and asynchronous; or
- orchestrated and synchronous/asynchronous.
In a decentralized and synchronous communications pattern, each service receives flow control, makes subsequent synchronous calls to other services and passes control to the next service.
In choreographed and asynchronous service communications, the service publishes events to a central message queue that distributes those events. In both approaches, there is no statement of overall system behavior in one place. Business flow logic is either embedded inside the services or in the event bindings between the producers and consumers.
The third approach, centralized orchestration, enables both synchronous and asynchronous communication. The orchestrator sequences the various service calls based on a defined workflow. That sequence is not embedded within the participating services. The business workflow knowledge resides in a centralized place, and the services focus solely on their individual responsibilities. This approach enables a simple, decoupled architecture that is easy to read. It also helps support interoperability between protocols and payload transformation between services.
Tradeoffs of synchronous and asynchronous communication
Synchronous communication is simpler in design but carries the risk of spreading failures across services. To mitigate that risk, the architect must implement sophisticated service discovery and application load balancing among microservices.
On the other hand, asynchronous communication trades architectural simplicity and data consistency for resilience and scalability. Asynchronous designs often provide better control over failures than synchronous setups. Consider starting with a synchronous system to optimize for speed of evolution and switching to asynchronous communications once your microservices architecture grows.
To enable both synchronous and asynchronous microservices communication, keep flow sequencing away from the individual services. Service-based flows are difficult to decouple. Instead, design an architecture that supports both asynchronous and synchronous communication. Then, allow your orchestrator to switch the communication pattern for the specific service (see the figure).
Editor's note: Joel Shore contributed to a past version of this article, which has been updated with microservices design information in 2020 by Priyank Gupta, solutions consultant, Sahaj Software.
Learn how to support asynchronous and synchronous Web services using J2EE
Discover the pros of asynchronous replication
Why is asynchronous communication the preferred messaging method in distributed architectures?