Scaling Vert.x Applications with Clustered Event Bus
Learn how to enable Vert.x Event Bus clustering with Hazelcast, run a simple chat service across nodes, and understand the trade‑offs involved.
22 Dec 2025, 22:55 UTC

Problem: scaling messaging across Vert.x instances
When a single Vert.x instance cannot handle the message load or you need fault tolerance, you want publishers and subscribers to stay in sync even if they connect to different nodes.
Thesis: enable the built‑in clustered Event Bus with Hazelcast
By adding the vertx‑hazelcast dependency and starting Vert.x with clustering turned on, the Event Bus automatically discovers peers and replicates messages, giving you horizontal scaling without changing your application code.
1. Add the clustering dependency
# Maven coordinates (replace ${vertx.version} with your Vert.x version)
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>${vertx.version}</version>
</dependency>
Run mvn clean package in the project directory; you need read access to the repository and write access to the target folder.
2. Provide a Hazelcast configuration
You can use the default multicast discovery or supply an XML file. Example hazelcast.xml:
<hazelcast>
<network>
<join>
<multicast enabled="true"/>
</join>
</network>
</hazelcast>
Place this file on the classpath (e.g., src/main/resources/hazelcast.xml).
3. Start Vert.x with clustering enabled
From the command line, launch two instances:
# Terminal 1
java -jar target/my-vertx-app.jar -cluster
# Terminal 2 (different host or same host with a different port offset)
java -jar target/my-vertx-app.jar -cluster -Dvertx.cluster.port_offset=1000
You need execute permission on the JAR. The -cluster flag tells VertxOptions to set setClustered(true). Each JVM will log a line similar to Members [2] { ... } indicating Hazelcast discovered the peer.
4. Worked example: a simple chat verticle
public class ChatVerticle extends AbstractVerticle {
@Override
public void start() {
// Subscribe to a shared address
vertx.eventBus().consumer("chat.messages", msg -> {
System.out.println("Received: " + msg.body());
// Echo back to all participants
vertx.eventBus().publish("chat.messages", msg.body());
});
// Optionally allow a client to send a message
vertx.eventBus().consumer("chat.input", msg -> {
vertx.eventBus().publish("chat.messages", msg.body());
});
}
}
Deploy the verticle in each instance (e.g., via vertx.deployVerticle(new ChatVerticle()) in the main verticle). Any message published to chat.messages on one node appears on all nodes, demonstrating horizontal scaling.
Trade‑offs and limitations
- Latency: Each event bus hop now involves Hazelcast’s distributed data structure, adding network round‑trip time compared to a local bus.
- Memory overhead: Hazelcast maintains in‑memory copies of messages and cluster state; monitor heap usage.
- Network partitions: Without split‑brain protection, a partition can cause two sub‑clusters to diverge. Enable Hazelcast’s split‑brain protection or use a TCP‑based discovery with a reliable network.
- Version compatibility: All nodes must run the same Vert.x and Hazelcast versions; mismatches prevent cluster formation.
To verify the cluster is healthy, look for the Hazelcast member list in the console (Members [size=2] ...) or connect Hazelcast Management Center (http://localhost:8080/mancenter) and check the cluster size metric.
Actionable closing
If you need to scale your Vert.x messaging beyond a single node, start with the steps above: add the vertx‑hazelcast dependency, supply a basic Hazelcast config, launch with -cluster, and deploy your event‑bus handlers unchanged. Monitor latency and heap, and configure split‑brain protection if your deployment spans unreliable networks. This gives you a fault‑tolerant, horizontally scalable Event Bus with minimal code changes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.