When microservices communicate asynchronously, a messaging system sits at the centre of the architecture, and its characteristics become the characteristics of the whole. Its throughput limits how fast the services can exchange work, its latency adds to every message's journey, and its behaviour when something fails determines whether data is delayed, duplicated or lost. Performance discussions often concentrate on the services themselves and treat the broker as plumbing. In practice, the broker is a distributed system with its own scaling rules, bottlenecks and failure modes, and teams that understand it can design services that use it well. This article looks at how common messaging approaches work and what they imply for performance.

How do brokers such as Kafka affect performance?

Two families are in wide use. Traditional queue brokers such as RabbitMQ deliver each message to a consumer and then remove it, with routing rules for directing messages and acknowledgements for confirming handling. Log-based platforms such as Apache Kafka append messages to a partitioned, replicated log that is retained for a period, and consumers track their own position, called an offset. Sequential disk writes, batching and zero-copy transfers let such systems sustain very high throughput. Retention allows new consumers to replay history and lets a slow consumer catch up without losing data. The trade-off is that tuning batch sizes and acknowledgement settings trades latency against throughput and durability, and these choices should be made deliberately.

Advertisement

How does asynchronous communication affect scalability?

Scalability comes from partitioning. A topic is divided into partitions, and each partition is processed by one consumer in a group at a time, so adding consumers increases parallelism up to the number of partitions. Messages with the same key go to the same partition, which preserves their order while spreading different keys across the cluster. This shapes design. Too few partitions limit parallelism, and a skewed key concentrates traffic on a single partition and creates a hot spot. Decoupling also helps absorb bursts, since producers can continue while consumers work through a backlog, provided the backlog is monitored and consumers can eventually catch up. Elastic scaling of consumers in response to queue depth is a common pattern.

Common failure modes

Several problems recur. Consumer lag grows when consumers fall behind producers, and it should be measured in both message count and age. Rebalancing, in which partitions are reassigned when consumers join or leave, can pause processing, and frequent rebalances caused by slow handlers or unstable instances hurt throughput. A poison message that always fails can block a partition unless it is moved to a dead-letter destination after limited retries. Delivery guarantees require care, because at-least-once delivery means duplicates, and consumers must be idempotent. Exactly-once processing is available within certain boundaries, with added cost, and it does not remove the need to think about side effects outside the platform. Capacity planning should include disk, network and replication overhead.

Why it matters

Asynchronous messaging is a strong foundation for microservices when it is understood and a source of mysterious slowdowns when it is not. Choosing an appropriate broker, designing partition keys with care, monitoring lag and age, handling failures explicitly and making consumers idempotent turn it into a predictable part of the system. The performance of the architecture then depends on decisions that the team has made on purpose.

In an asynchronous architecture the broker is not plumbing. It is the part of the system that decides how fast everything else can go.

Sources

  1. Apache Kafka documentation