Why Services Communicate
In a monolith, modules call each other through in-process function calls — fast, simple, and transactional. In a distributed system, each service runs in its own process (often its own container or VM), so calling another service means crossing a network boundary. That boundary introduces latency, partial failures, and the need for explicit contracts. Service communication falls into two broad families. Synchronous communication blocks the caller until the callee responds — like REST over HTTP or gRPC. Asynchronous communication sends a message and moves on — the receiver processes it later via a queue or event bus. Neither is universally better; the choice depends on whether the caller needs an immediate answer, whether failures should block the workflow, and how tightly coupled the services should be.