Clustered Request-Reply on the Vert.x Event Bus
Use Vert.x event bus request-reply for intra-cluster verticle communication without dedicated HTTP endpoints, with caveats around durability and exactly-once delivery.
20 Feb 2026, 07:13 UTC

Internal verticle communication without HTTP sprawl
You have two verticles on different cluster nodes. One needs data from the other, and you do not want to open a dedicated HTTP endpoint just for internal calls. The Vert.x event bus offers request-reply messaging: a sender publishes to an address, a consumer handles it, and the result comes back through a reply handler or future. This works within a single Vert.x instance and, with a cluster manager, across nodes.
Useful takeaway: treat the clustered event bus as an RPC-style transport, not a durable queue. Messages can be lost if no consumer is listening, delivery is not exactly-once, and large payloads increase serialization cost.
How clustered request-reply works
A Vertx instance is the Vert.x runtime. When you set setClustered(true) in VertxOptions and include a cluster manager such as Hazelcast, Infinispan, or Redis, Vert.x connects nodes over the network. The event bus then routes messages between verticles regardless of which node they run on.
Message codecs convert Java objects, JSON, buffers, or primitives into bytes for network transport. Vert.x handles serialization automatically when a message crosses a node boundary, but you must register custom codecs for complex types if the default serialization is not suitable.
Handlers subscribe to addresses. Wildcard patterns such as orders.* can match multiple addresses. Unregister handlers when a verticle stops; otherwise stale subscriptions can keep objects in memory and prevent garbage collection.
Worked example: inventory check across two nodes
This example assumes Vert.x 4.x and a Maven or Gradle project. Add a cluster manager dependency. For Hazelcast:
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>{vertx-version}</version>
</dependency>
Run this from your project root with Maven or Gradle. No special OS permissions are required, but the cluster ports must be reachable between nodes.
Create a clustered Vert.x instance:
VertxOptions options = new VertxOptions().setClustered(true);
Vertx.clusteredVertx(options, on -> {
if (on.succeeded()) {
Vertx vertx = on.result();
// deploy verticles here
} else {
on.cause().printStackTrace();
}
});
The requesting verticle sends a message and waits for a reply:
vertx.eventBus().request("inventory.check", "sku-12345", on -> {
if (on.succeeded()) {
String stock = on.result().body().toString();
System.out.println("Available stock: " + stock);
} else {
on.cause().printStackTrace();
}
});
The replying verticle registers a consumer and calls reply():
vertx.eventBus().consumer("inventory.check", msg -> {
String sku = msg.body().toString();
String stock = lookupStock(sku); // your lookup logic
msg.reply(stock);
});
Deploy both verticles on separate nodes. Node A sends to inventory.check; node B receives it and replies. Vert.x routes the reply back to the original sender.
Expected checks and risks
- Check that cluster formation logs appear on both nodes before sending messages.
- Verify the reply arrives within your timeout;
request()fails if no reply comes back. - Risk: if node B crashes after receiving the request but before replying, node A gets a failure. Design the handler to be idempotent in case of redelivery.
- Risk: large objects increase serialization time and cluster traffic. Send an ID or reference instead of the full payload when possible.
Limitations and how to verify
The clustered event bus is not a durable message queue. If no consumer subscribes to an address when a message is published, the message is dropped. It also does not guarantee exactly-once delivery; a node failure can cause redelivery after recovery.
Practical verification: start two local Vert.x instances with clustering enabled, deploy the consumer on one and the producer on the other, send a request, then kill the consumer node. Observe whether the producer receives a failure, whether the handler re-registers after restart, and whether any messages are lost. Compare the behavior against your idempotency requirements before using this in production.
Closing
Use the Vert.x event bus for lightweight, RPC-style communication between verticles when you want to avoid HTTP endpoints for internal traffic. Add a cluster manager, enable clustering in VertxOptions, keep payloads small, unregister handlers on shutdown, and assume messages can be lost or redelivered. Test locally with two nodes and a failure scenario before deploying to a cluster.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.