Introduction

While Akka Actors is one possible solution to concurrent processing, there are other options on the market. One alternative that seems quite similar on the first look is Vert.x. However, there are a few notable differences. This article will focus on some key concepts in concurrent processing and explain the differences between Akka and Vert.x.

For the code referenced in this article, please check out our Github.

1. Threading

Akka Actors are similar to Verticles in Vert.x in the sense that both are the unit of execution. Similar to Actors, Verticles are running on the event loop by default, which is essentially a thread pool that shall not be blocked. Vert.x offers a convenient way of executing blocking code inside of Verticles that are running on the event loop. Using the specific notation, only the blocking part of the code will be run on a separate worker pool, making sure the event loop is not blocked.


vertx.executeBlocking(promise -> {
  // Call some blocking API that takes a significant amount of time to return
  String result = someAPI.blockingMethod("hello");
  promise.complete(result);
}, res -> {
  System.out.println("The result is: " + res.result());
});

While a verticle is bound to a thread when it is started and will stay on that thread until it is terminated, threads in Akka might be disbanded if they stay idle too long. Akka does not guarantee that the actor will be running on the same thread on a restart.

2. Message Delivery

There is a quite significant difference when it comes to how messages are delivered between actors or verticles. Akka only supports point-to-point message delivery, meaning that each message will be sent from one actor and processed from one actor. Messages have the format of scala or java objects and the types of messages have to be specified (unless you are using Akka classic). Meanwhile, Vert.x also supports pub/sub messaging, meaning that multiple actors can produce to- and consume from a shared channel. Messages in Vert.x are by default written in json, although the use of codecs enables sending objects, and are transported by the event bus.


eventBus.registerCodec(myCodec);

DeliveryOptions options = new DeliveryOptions().setCodecName(myCodec.name());

eventBus.send("orders", new MyPOJO(), options);

This approach makes Vert.x language agnostic in the sense that a Vert.x instance can be composed of Verticles that are written in any language supported by Vert.x. Akka on the other hand only supports scala and java actors.

3. Fault Tolerance & Delivery Guarantees

A potentially significant advantage of Akka over Vert.x is the fact that actors are organized in hierarchies, while the Verticles are organized flat. This hierarchy can be crucial when it comes to gracefully handle failures because they can be bubbled up inside the hierarchy.

Actor HierarchyActor Hierarchy

Further, Akka persistence enables Actors to recover their former state when they crash, which is something that Vert.x does not deliver out of the box. As a consequence, Akka can provide both at-most-once and at-least-once delivery guarantees, while Vert.x only supports at-most-once.

Wrapping it Up

Concluding the comparison, although both libraries seem similar at first, there are good reasons for choosing each of them over the other. Vert.x strengths lay in its convenient way of executing blocking code, the event bus which enables Vert.x to be somewhat language agnostic, and the support of pub/sub messaging. Akka on the other hand has a big advantage regarding the graceful handling of failures by the actor hierarchy, as well as Akka persistence enabling Akka to guarantee at-least-once delivery. These points should be taken into consideration when choosing the correct library for your use case.

For the next part of the tutorial please click here!