Mercure.rocksSponsored by



This release is built on top of Caddy 2.6. Caddy 2.6 removed support for single-hyphen long-form flags (such as -config), use the double-hyphen syntax instead (--config).


The mercure_subscribers field of the Prometheus endpoint has been renamed mercure_subscribers_connected for better interoperability (including with Datadog).


The default dev key changed from !ChangeMe! to !ChangeThisMercureHubJWTSecretKey! to respect the specification (they key must longer than 256 bits).


The query parameter allowing to fetch past events has been renamed lastEventID: in your clients, replace all occurences of the Last-Event-ID query parameter by lastEventID.

Publishing public updates in topics not explictly listed in the mercure.publish JWT claim isn't supported anymore. To let your publishers publish (public and private updates) in all topics, use the special * topic selector:

   "mercure": {
-    "publish": []
+    "publish": ["*"]

Backward compatibility with the old version of the protocol (version 7) can be enabled by setting the protocol_version_compatibility directive to 7 in your Caddyfile.


The DEBUG environment variable has gone. Set the GLOBAL_OPTIONS environment variable to debug instead.


The Hub is now available as a module for the Caddy web server. It is also easier to use as a standalone Go library. We still provide standalone binaries, but it's now a custom build of Caddy including the Mercure module.

Builds of the legacy server are also available to ease the transition, but starting with version 0.12 only the Caddy-based builds will be provided (they have the legacy prefix).

Relying on Caddy allows to use the Hub as a reverse proxy for your site or API that also adds the Mercure well-known URL (/.well-known/mercure). Thanks to this new feature, the well-known URL can be on the same domain as your site or API, so you don't need to deal with CORS.

All features provided by Caddy are also supported by this custom build: HTTP/3 and h2c support, compression, Prometheus metrics (with additional Mercure-specific metrics), profiler (/debug/pprof/)...

Before switching to the Caddy build, be sure to migrate your configuration.


This version is in sync with the latest version of the specification, which changed a lot. Upgrading to 0.10 requires to change your code. Carefully read this guide before upgrading the hub.

  • Private updates are now handled differently. Targets don't exist anymore. They have been superseded by the concept of topic selectors. To send a private update, the publisher must now set the new private field to on when sending the POST request. The topics of the update must also match at least one selector (a URI Template, a raw string or * to match all topics) provided in the mercure.publish claim of the JWT. To receive a private update, at least one topic of this update must match at least one selector provided in the mercure.subscribe claim of the JWT.

  • The structure of the JSON-LD document included in subscription events changed. Especially, "@type": "" is now "type": "Subscription" and "@id": "/.well-known/mercure/subscriptions/foo/bar" is now "id": "/.well-known/mercure/subscriptions/foo/bar".

  • The dispatch_subscriptions config option has been renamed subscriptions.

  • The subscriptions_include_ip config option doesn't exist anymore. To include the subscriber IP (or any other value) in subscription events, use the new mercure.payload property of the JWT.

  • All IDs generated by the hub (updates ID, subscriptions IDs...) are now URN following the template urn:uuid:{the-uuid} (it was {the-uuid} before). You may need to update your code if you deal with these IDs.

  • The topic * is now reserved and allows to subscribe to all topics.


  • According to the new version of the spec, the URL of the Hub changed moved from /hub to /.well-known/mercure

  • HISTORY_CLEANUP_FREQUENCY, HISTORY_SIZE and DB_PATH environment variables have been replaced by the new TRANSPORT_URL environment variable

  • Lists in ACME_HOSTS, CORS_ALLOWED_ORIGINS, PUBLISH_ALLOWED_ORIGINS must now be space separated

  • The public API of the Go library has been totally revamped