I’m very pleased to announce the immediate availability of the Mercure.rocks hub version 0.14.
Mercure is a free and open-source solution for real-time communication. With Mercure, securely push data to all your connected users with a simple POST request. No third-party library or SDK is required: the browser (or any other type of client) receives the data through a server component that we call a hub, and issues a JavaScript event that your code can subscribe to.
Performance and Memory Usage Improvements
Mercure is becoming a very popular technology. It just reached 3,000 stars on GitHub and is now being used for high-profile projects by organizations including the UN, UEFA, Lush, Intermountain Healthcare, and the M6 media group.
It is also used by very high-traffic public projects such as Mail.tm, an email service that helps users to protect against spam, bots, phishing, and other online abuse without exposing their real email addresses. Mail.tm sends about 8 million notifications per day running a single Mercure hub on a €6.90/month server (read the full case study). These kinds of deployments are a gold mine to optimize the hub as much as possible! And thanks to the team behind Mail.tm and the community, it’s what has been done during the development of this version!
First, we improved memory usage and fixed some leaks, especially the logger and the Prometheus integration. After these initial improvements, we detected that the CPU usage was spiking when there were a large number of subscribers connected. Kevin Burns proposed a patch that dramatically improves CPU usage, especially under very high loads. Under the bonnet, Kevin’s patch uses a new Go library he created, skipfilter, which combines skiplists with roaring bitmaps. According to the benchmarks written by Kevin, the new algorithm is 20 to 50% more efficient than the previous one. This patch reduced the CPU usage on the machine running Mail.tm’s Mercure hub from 100% to ~10%!
Automatic Disconnection When the JWT Expires
Mercure supports dispatching updates only to authorized clients. To do so, the client must provide a signed JSON Web Token (JWT) to the hub. This JWT must contain a list of topics (or topic selectors) the client can subscribe to which the client can subscribe and receive private updates.
If the standard exp
claim of the JWT is set, the token cannot be used anymore when expired.
Starting with Mercure 0.14, Mercure clients are automatically disconnected when the JWT expires. Thanks to the native reconciliation system provided by Mercure (via Server-Sent-Events), after disconnection the client will automatically reconnect and recover any events missed during disconnection, as long as a new, unexpired JWT has been generated.
Configurable Authorization Cookie Name
When using authorization, the JWT can be passed to the Mercure hub through a cookie named mercureAuthorization
or the Authorization
HTTP header.
Sometimes, it can be convenient to have several Mercure hubs on the same domain. Unfortunately, this creates naming conflict because of the fixed name of the cookie. With Mercure 0.14, the cookie name can now be configured, to allow using several hub on the same domain.
Ability To Pass the JWT Using a Query Parameter
Since day 1, Mercure support passing the JWT to the hub using a cookie or the Authorization
HTTP header. It’s now also possible to use a query parameter named authorization
. This new method is hard to secure and its usage is discouraged. Using a cookie or the Authorization
header should always be preferred, but it can be convenient for complex cross-domain scenarios.
To use this method securely, the connection must be encrypted (which is required by the Mercure specification), and great care must be taken to not log the JWT. The Mercure.rocks hub redactsthe authorization
query parameter (as well as cookies and the Authorization
header) by default. To do so, we contributed new log filters to the Caddy web server, the web server we use under the hood.
Caddy Server 2.5
Speaking of Caddy, Mercure 0.14 is now built on top of Caddy 2.5. Checkout Caddy’s changelog to discover all the new features it includes! You can use all of them with Mercure by customizing the provided Caddyfile
.
Reminder: the Mercure hub is also available as a Go HTTP middleware, which can be embeded in any application (typically web servers) written in Go.
Upgrade Guide and Backward Compatibility
A few changes introduced in version 0.14 may require to update your clients. Be sure to read the upgrade guide!
Even if the changes are slight and should not affect most users, we take backward compatibility very seriously, and it’s possible to enable compatibility with older versions of the public protocol by setting the new protocol_version_compatibility
directive we introduced in version 0.14.
Managed and High Availability Versions
The managed version of Mercure.rocks as well as the HA version we sell are already built on top of v0.14 and support all features listed in this blog post.
If you use the managed version, you can upgrade to the latest version directly from the settings page. New projects are directly created using it.
Customers of the High-Availability version can download the binaries and Docker images via the usual update channels.
Meet the Community at API Platform Con
Many Mercure, real-time and async API specialists including Fran Mendez (creator of AsyncAPI), , Pauline Vos (Websockets expert), Francis Lavoie (Caddy server Core Team), Brian McLusey (Mercure expert) and myself will be speaking in less than 2 weeks at the API Platform Conference. The conference takes place in my hometown of Lille (30mn from Brussels, 1h from Paris, 1h30 from London) and online. There is still time to buy your tickets!
Bug Reports and Support
As usual, don’t hesitate to report any bugs on GitHub. If you want to support the project, consider buying the managed or the HA version, or sponsoring me.
If you need help creating your next real-time app, Les-Tilleuls.coop can help!
Bonus: Twitter Space About Mercure
If you speak French, you may be interested in listening to the recording of this Twitter Space about Mercure 0.14:
“Starting with Mercure 0.4, Mercure clients are automatically disconnected when the JWT expires.”
Pretty sure you mean “0.14” here 😉
“Since day 1, Mercure support passing the JWT to the hub using a cookie or a JWT.”
Passing the JWT using a JWT?
Thanks noop, fixed!