FileWave: why we moved from ZeroMQ to NATS

FileWave Device Management System
Filewave is a cross-platform/multi-platform Device Management System that helps big organizations to manage their devices from a single interface.
We are able to manage devices of different platforms:
-
Windows
-
macOS
-
iOS
-
Apple TV
-
Android
-
Chromebook
and we’re able to:
-
Get inventory data (CPU, RAM, free disk space, …)
-
Install software and updates
-
Send specific commands (reboot, lock , …) to devices
FileWave Before NATS
Before we switched to NATS, the internal messaging was implemented using ZeroMQ.
ZeroMQ is a library that offers several mechanisms and patterns to implement a lot of different communication strategies. It works well but has several limitations (for our use case):
-
It’s just a library: so we had to implement a “central” server
-
A single socket can use just a single pattern; if you need a PUB/SUB and a REQ/REPLY you have to open two sockets
-
Not supported in web applications; the messaging with the WEB interfaces was implemented by “converting” ZeroMQ messages and sending them to the UI using SSE (Server Sent Event)
-
It does not support out-of-the-box TLS
-
It does not support use cases that require persistence
Why we needed to migrate
The main drivers for migrations were:
-
We have strict requirements for having TLS on all communication channels
-
We need support for web applications
-
Message persistence and replay are something we’ll need to use soon
Why NATS?
We did some research based on our needs:
-
Client libraries for (at least) C/C++, Python, Web Browsers
-
Cloud-ready/friendly
-
mTLS support
-
Easy to install/configure and monitor
-
With good documentation and community
And we found a few candidates:
-
RabbitMQ
-
Kafka
-
NATS
We decided then to do some parallel investigations and, based on our specific use cases - we decided that NATS was the best choice for us.
The main drivers for picking NATS were:
-
Easy to integrate into our installers (thanks to Go)
-
By far the simplest to install and configure
-
Very small install size and memory footprint (thanks to the Go engine)
-
Pre-built binaries for all platforms we need to support
-
Wide-range of authentication systems (for instance we use mTLS for devices and server components and JWT for authenticating users on User Interfaces)