# Real-time updates {#real-time-updates}


Once your Shlink instance is set up, you may want to enable real-time updates to notify third parties when certain events occur.

Currently, Shlink supports the next technologies to publish updates.

- [Mercure hub](https://sourcey-shlink.pages.dev/documentation/advanced/real-time-updates/index.md#mercure-hub-server): allows to subscribe to server-sent events. _(Since v2.2.0)_.
- [RabbitMQ](https://sourcey-shlink.pages.dev/documentation/advanced/real-time-updates/index.md#rabbitmq-server): to publish server-to-server updates _(Since v2.10.0)_.
- [Redis pub/sub](https://sourcey-shlink.pages.dev/documentation/advanced/real-time-updates/index.md#redis-pub-sub): to publish server-to-server updates _(Since v3.2.0)_.



> [!WARNING]
> Real-time updates only work with [RoadRunner](https://sourcey-shlink.pages.dev/documentation/supported-runtimes/serve-with-roadrunner/index.md), which is the
> case if you are using the [docker image](https://sourcey-shlink.pages.dev/documentation/install-docker-image/index.md).




## Topics and payloads {#topics-and-payloads}


Regardless the technology used for publishing and subscribing to updates, the whole list of supported topics, together with their payloads can be found in Shlink's [Async API spec](https://api-spec.shlink.io/async-api) page.


## Mercure hub server {#mercure-hub-server}


The best option if you want to get real-time updates on a client-side web app, is by taking advantage of the integration with a [mercure](https://mercure.rocks) hub server.

Mercure provides server-sent events, so that consumers can subscribe to topics and get automatically notified when Shlink publishes an update for any of them.


### Configure the mercure hub server {#configure-the-mercure-hub-server}


The mercure hub server will act as an intermediary between Shlink, which will publish updates on it, and consumers, which will subscribe to those updates and get notified by the hub.

The first thing you need to do is [install the mercure hub](https://mercure.rocks/docs/hub/install) server. There's both a prebuilt dependency-less binary, and a docker image, which is the best option to use together with Shlink's docker image.

Then you need to provide some config options to the mercure hub for the integration to properly work:


#### For new mercure versions (since 0.11): {#for-new-mercure-versions-since-011}


- `SERVER_NAME`: This env var should have the value `":80"`, in order to disable https. Just make sure you [serve mercure behind a reverse proxy](https://mercure.rocks/docs/hub/cookbooks#using-nginx-as-an-http-2-reverse-proxy-in-front-of-the-hub), and enable https there.
- `MERCURE_PUBLISHER_JWT_KEY` and `MERCURE_SUBSCRIBER_JWT_KEY`: The same value provided to Shlink should be used for these two env vars, otherwise, the JWTs generated by Shlink will be rejected by mercure and neither publishing nor subscribing will be possible.
- `MERCURE_EXTRA_DIRECTIVES`: if you want to consume updates from a browser web app (like shlink-web-client), this option should have the directive `cors_origins` followed by the domain/s from which you plan to consume mercure (for example `cors_origins https://app.shlink.io`), otherwise, it will reject the connection.


#### For legacy mercure versions (before 0.11 or using _legacy_ prefix): {#for-legacy-mercure-versions-before-011-or-using-legacy-prefix}


- `--jwt-key`|`JWT_KEY`: The same value provided to Shlink should be used here, otherwise, the JWTs generated by Shlink will be rejected by mercure and neither publishing nor subscribing will be possible.
- `--cors-allowed-origins`|`CORS_ALLOWED_ORIGINS`: if you want to consume updates from a browser web app (like shlink-web-client), this option should have the domain/s from which you plan to consume mercure (for example `"https://app.shlink.io"`), otherwise, it will reject the connection.


### Interaction between the parts {#interaction-between-the-parts}


Once installed, this is how Shlink, the mercure hub and consumers will interact:





```mermaid
sequenceDiagram
  Shlink->>Consumers: Get mercure URL and JWT
  Consumers-->>Mercure hub: Subscribe to topics
  Shlink->>Mercure hub: Publish updates
  Mercure hub-->>Consumers: Receive updates
```





- Shlink knows Mercure hub's public URL and the JWT secret key.
- Shlink can generate JWTs for mercure, which only have permission for subscribing.
- Shlink publishes updates to mercure when something needs to be notified to consumers.
- Consumers get valid JWTs and the hub URL from Shlink's REST API, by calling the [mercure info endpoint](https://sourcey-shlink.pages.dev/documentation/api/index.md#operation-rest-v-version-mercure-info-get).
- Consumers subscribe to topics on the mercure hub using the JWT returned on previous request.
- If the JWT expires, consumers can call the endpoint as many times as they need to get new JWTs.

This flow ensures the JWT key is never leaked by accident, and you need to have a valid Shlink API key in order to get valid JWTs for mercure.

Also, JWTs returned to consumers will only have permission to subscribe to updates. Only Shlink will be able to publish updates.



> [!IMPORTANT]
> **Note**
>
> If you use shlink-web-client to interact with your Shlink instance, it will work out of the box and consume updates
> from mercure, updating the UI in real-time where applicable.




## RabbitMQ server {#rabbitmq-server}


Starting with v2.10.0, Shlink supports publishing updates in a [RabbitMQ](https://www.rabbitmq.com/) server, which is a widely used technology for publishing and subscribing to server-to-server updates.


### Configure the RabbitMQ server {#configure-the-rabbitmq-server}


The RabbitMQ server will act as an intermediary between Shlink, which will publish updates on it, and consumers, which will subscribe to those updates and get notified in real-time.

There are several ways to install RabbitMQ. The best option is to follow the [official documentation](https://www.rabbitmq.com/download.html).

Once the server is configured, you can provide the integration config to Shlink via [installation tool](https://sourcey-shlink.pages.dev/documentation/command-line-interface/installation-tool/index.md) or [env vars](https://sourcey-shlink.pages.dev/documentation/environment-variables/index.md#rabbitmq-integration).


### Exchanges and queues {#exchanges-and-queues}


Shlink will create an exchange with its corresponding queue, for every operation defined in Shlink's [Async API spec](https://api-spec.shlink.io/async-api/).

The exchanges and queues are created in a "durable" way, with "direct" publishing type.


## Redis pub/sub {#redis-pubsub}


Since Shlink v3.2.0, if you configured a redis server/cluster for caching, Shlink can also use that instance for real-time updates via redis pub/sub.

When this happens, the redis server/cluster will act as an intermediary where Shlink publishes the updates, and others can subscribe to them.
