Hulaaki vs GenMQTT

I am setting up MQTT server with VerneMQ as a broker. I have to receive messages from a client and store them in a database (OrientDB) on the server. For server side, we largely rely on Elixir as our backend. So, now I have to select one of those but due to lack of resources, I cannot find anything which objectively compares these two libraries for connecting with MQTT brokers. Please find the links below.

Also, do these support interoperability with different MQTT brokers available?
How well do these handle multiple pubs and subs (connections) from and to various clients?
Hulaaki supports SSL/TLS but I couldnt’ find similar feature in GenMQTT?

Why are we using MQTT?
MQTT is being used to send push notifications from our server to mobile users, and receive messages from server to client and client to client.

GenMQTT and Hulaaki


Hi. I did the GenMQTT project that wraps an Erlang module called gen_emqtt that was written by Erlio for their VerneMQ MQTT broker. gen_emqtt used to be in a separate project called vmq_commons, but that project has been moved into the vernemq application, and hence the gen_emqtt is no longer available without getting the entire VerneMQ broker.

GenMQTT is thus deprecated, because I am not going to maintain the Erlang library, since it has some flaws—a proper error kernel being one of them. I am working on an implementation in pure Elixir, and I have some different approaches than Hulaaki. I don’t know how long this will take as I have a fulltime job that doesn’t relate to MQTT.

As for now I would recommend looking into both Hulaaki and GenMQTT; if you decide to go with GenMQTT I will happily accept pull requests.

1 Like

For now, I think I will go with Hulaaki as it gives me the option to test other brokers too.

If you don’t mind then answer follow-up questions.

  1. What particular approach did you find in Hulaaki’s implementation?
  2. If you could share some insights on your novel approach then maybe I can generate a pull request in Hulaaki for the same. This can help Hulaaki become one place for Elixir + MQTT lovers.

Don’t know what you mean by «testing with other brokers»; GenMQTT should work fine with any broker that implement the MQTT protocol.

I am still considering my design, but basically I want an application that handle the MQTT semantics so the user will interact with something that kinda work like a MQTT broker and when messages arrives they should arrive to the process mailbox (in a GenServer/GenStateMachine they would show up as info-messages), so: Processes in your app subscribe to an internal app that handle the actual subscription to topics; dealing with QoS; and dealing with severed connections to the MQTT broker. The internal app will monitor the subscribing processes and unsubscribe from topics as subscribing processes are terminated (depending on the error reason)—disconnects and reconnects should also get communicated to the processes.

I also have ideas of handling publish with call and cast, where call would result in a message with a QoS greater than 0 that will block the caller until the message has been delivered to the broker, and cast which will be a fire-and-forget.

I have browsed through the Hulaaki source, and I could do Pull Requests, but I think I want different things and I don’t want to do a hostile takeover of the design direction. Besides more options are always good for the community.

1 Like

I agree with this for pivotal design changes like the one you have in mind.

I was hoping if there were minor changes then they could’ve been easily incorporated into the Hulaaki library. If you start working on your version of MQTT client I would be interested to contribute and put it to use.

1 Like


I’m planning on using mqtt again. I used to use genmqtt (thanks to @gausby) =) But I see that there is now a new client called tortoise and hulaaki is still available. Just wondering if I should switch over to do mqtt client pub sub requests?

I’m currently using elixir 1.5.

Thanks =)

1 Like

Hi, I am the author of Tortoise (as well as the gen_mqtt client/wrapper)

Tortoise is the successor to gen_mqtt; it doesn’t quite work the way I described in a previous post (I have a full time job and all that, so time is scarce which conflicts with really ambitious projects) but I think Tortoise is really nice at separating the MQTT semantics from the Elixir semantics; right now it support publishing and subscribing to topics with Quality of Service 0 through 2; TCP and SSL transports, and it behaves pretty well when it reconnect to the broker.

I still have some way to go before I can call it 1.0, but I’d say it is usable now; everyone who uses gen_mqtt should switch to Tortoise. Don’t be shy if you have any questions :slight_smile:


Oh yeah, I currently use Elixir 1.6 for Tortoise. What is keeping you on 1.5 ?

Thanks! I just haven’t upgraded to 1.6 yet. =) I will try to upgrade and also check out Tortoise.

Might take you up on the questions part. Thanks! You guys are the best. =)


I guess I deserve the questions when I haven’t written documentation yet :slight_smile:

You have to implement a callback module for handling the incoming traffic; you can see examples of these in the Tortoise.Handler.Logger, which implement the Tortoise.Handler-behaviour. The key is to do non-blocking calls here, as the process running the handler is the process that own the main controller—in other words, use it to pattern match on the incoming data and dispatch it to other processes!

When you have a connection you can use the client_id you used for the connection in the Tortoise.publish/4. If you publish with a QoS you will get a message in your process mailbox when the message has been handed over to the server—there is a Tortoise.publish_sync/4 variant that will block the calling process until it has been delivered (this of course only make sense for messages with a quality of service bigger than 0, as 0 is a fire and forget)

So: You have to implement a callback behaviour called Tortoise.Handler for receiving messages, which should do as little as possible; just dispatch messages to the rest of the system; and you should use the Tortoise.publish/publish_sync to publish to the broker; then Tortoise should handle the details of the protocol!