Updated Sep 5, 2026

Shared subscriptions

Distribute live messages across backend workers and verify delivery using your private RunMQTT Broker.

Use a shared subscription when several backend workers should divide the messages matching a topic filter. Ordinary subscriptions send a copy to every matching subscriber. A shared subscription selects one member of a group for each matching message; it does not wait for your application to finish a database write or other business operation.

Subscription format

$share/<group>/<topic-filter>
$share/workers/demo/hello

Use a group name of 1–40 characters without /, + or #; short ASCII names such as workers keep configuration portable. The filter after the group is the actual topic filter. Use the same group and filter for workers that should divide the same stream. Each connection still needs a unique Client ID.

Publish to demo/hello, never to $share/workers/demo/hello. $share/ belongs to the subscription. Keep the filter in single quotes in shell commands so the shell does not expand $share.

Configure the RunMQTT identities

First complete the ordinary subscribe/publish test in the quickstart. For this test, reuse its device and the bidirectional demo/hello policy. For production, give the publisher publish access and each worker subscribe access to the actual topic using separate templates. The shared group is selected by the client subscription, not by creating a new Broker or sharing a Client ID.

The commands below use MQTT 5. Check the connection acknowledgement: if Shared Subscription Available is explicitly false, do not start workers with a shared filter. A rejected SUBACK must also stop the rollout. The ACL linter does not simulate group delivery; perform this check against your target Broker before scaling consumers.

Verify with two workers

Use three terminals and the MQTT_HOST, MQTT_USERNAME, MQTT_PASSWORD setup from the quickstart in each. Terminal A:

mosquitto_sub -h "$MQTT_HOST" -p 8883 --tls-use-os-certs \
  -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -i worker-a \
  -V mqttv5 -k 60 -q 1 -t '$share/workers/demo/hello' -v -d

Terminal B:

mosquitto_sub -h "$MQTT_HOST" -p 8883 --tls-use-os-certs \
  -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -i worker-b \
  -V mqttv5 -k 60 -q 1 -t '$share/workers/demo/hello' -v -d

Wait for both successful SUBACKs and allow five seconds, then publish from terminal C:

for n in 1 2 3 4 5 6; do
  mosquitto_pub -h "$MQTT_HOST" -p 8883 --tls-use-os-certs \
    -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -i demo-publisher \
    -V mqttv5 -k 60 -q 1 -t 'demo/hello' -m "sample-$n"
  sleep 1
done

Across A and B, each sample-N should be assigned to one worker during normal delivery. Six messages need not split evenly, and one worker may receive several in succession. QoS 1 redelivery can still produce duplicates; do not use this test to claim exactly-once processing.

Compare groups and ordinary subscribers

  • Start an ordinary subscriber to demo/hello with Client ID observer, then publish again. It should receive every new sample independently of the workers group.
  • Start another shared subscriber with Client ID audit-a and filter $share/audit/demo/hello. New messages should reach both the workers group and the audit group, with one selected member per group.
  • Stop worker A and publish again after disconnect detection. Verify that B receives new messages. Do not assume in-flight work completed on A or that old messages will be replayed.

Stop test clients with Ctrl+C and clear password variables. Messages published before subscriptions become active are outside this live-delivery test.

Processing and capacity boundaries

Shared subscriptions do not provide a durable offset, a replay log, strict round-robin fairness or per-device business ordering. Use event IDs and idempotent processing; use explicit topic partitions if one device's events must reach the same worker. Test disconnects with your actual SDK and session settings before relying on recovery.

Each connected worker counts as a connection. A message of at most 512 bytes delivered to one member in each of two groups consumes three message units: one publish and two deliveries. An ordinary observer adds another delivery. See plans and billing.