Asynchronous programming lets an operation finish independently of its caller and report a result or failure later. A service can keep processing requests instead of holding a thread idle while a remote call or database operation completes. This can improve responsiveness and allow the same resources to handle more work. section 8.0
In distributed applications, asynchronous message passing also reduces the need for both services to be available at the same moment. A sender places a message on a channel and continues working. If the receiving service is unavailable, a channel with buffering can retain messages until it can process them. This shifts delivery concerns into the channel; it does not make failures disappear. Messages, including errors, help keep services loosely coupled, while backpressure lets a consumer control the load it receives. section 9.3.1 section 9.2
Figure 9.4 The asynchronous communication failure propagation in microservices
The failure-propagation diagram illustrates messages waiting in channels while receiving services are unavailable. section 9.3.1
For a Quarkus microservice, MicroProfile Reactive Messaging provides channels between producers and consumers. Methods in CDI beans use @Incoming and @Outgoing; an Emitter can send from a method that is not itself a messaging method. SmallRye Reactive Messaging supplies the Quarkus implementation and connectors for remote brokers such as Kafka and RabbitMQ. Messaging does not require every handler to use reactive code: blocking APIs can also be used in Quarkus messaging integrations. section 9.10 section 9.4
Send an invoice after a reservation
Add the quarkus-messaging extension, then inject @Channel("invoices") Emitter<Invoice> into the reservation endpoint. After persisting a reservation, send an Invoice containing the reservation and its computed price. A local stub consumes it with @Incoming("invoices") before the channel is connected to a separate Billing service. Emitter.send returns a CompletionStage that can report failure; a MutinyEmitter alternative returns a Uni on which a failure handler can be attached. The billing request can run asynchronously because an unpaid reservation can be canceled later. section 9.4
For communication between services, attach a connector rather than treating an in-process channel as a remote link. The rental application uses Kafka between Rental and Billing and RabbitMQ between Reservation and Billing. These examples demonstrate the messaging API, not Kafka internals or a universal delivery guarantee. section 9.6 section 9.9



























