An example,
> Convert something to an async operation and your system will always return a success response. But there's no guarantee that the request will actually ever be processed successfully.
Great! I don't want service A to be coupled to service B's ability to work. I want A to send off a message and leave it to B to succeed or fail. This separation of state (service A and B can't even talk to each other directly) is part of what makes queues so powerful - it's also the foundation of the actor model, which is known for its powerful resiliency and scalability properties.
The author's suggestion of using synchronous communication with backpressure and sync failures is my last ditch approach. I have to set up circuit breakers just to make something like this anything less than a total disaster with full system failure due to a single service outage.
Like the author, the "good use cases for queues" is very nearly 100% for me. I believe you should reach for queues first, and it's worth remodeling a system to be queue based if you can help it.
Sometimes modeling as synchronous control is easiest, but I'm happy that I can avoid that in almost every case.
It's funny reading this after using Erlang/Elixir over the last few years. The default is always async with the assumption it will fail - as async processes failing is a core part of the OTP application architecture.
It's not something to be feared but a key part of how your application data-flow works.
Maybe I'm wrong and it's not so much work in the end. Hoping for some feedback.