Skip to content

Topics and Wildcards

eric edited this page Jun 12, 2026 · 1 revision

Topics and Wildcards

Topic mode adds MQTT-style hierarchical routing on top of the classic producer + event model. It is opt-in per subscription — existing subscriptions are unaffected, and the two models coexist on the same events.

Subscribing to a pattern

consumer.subscribe('org/acme/machine/+/cmd', (data, from, ack, raw) => {
    console.log('command on', raw.event, ':', data);   // raw.event = concrete topic
}, { mode: 'topic' });

Producers don't change anything — the event name is the topic:

producer.produce('org/acme/machine/m-01/cmd', 'restart');

Wildcard semantics

Symbol Matches Example
+ exactly one level org/acme/machine/+/cmd matches …/m-01/cmd, not …/a/b/cmd
# any number of trailing levels (must be last) org/acme/# matches org/acme/alert and org/acme/machine/m-01/cmd
  • Levels are separated by /.
  • # also matches zero levels (org/acme/# matches org/acme).
  • Matching is case-insensitive (consistent with event-name handling).
  • Topic subscriptions are producer-agnostic: any producer publishing a matching topic reaches the subscriber. Realm isolation still applies.

Composing with other features

Topic subscriptions accept all the usual options:

consumer.subscribe('org/acme/#', handler, {
    mode: 'topic',
    durable: true,                 // offline messages queue and replay
    ack: true,                     // at-least-once with retry/DLQ
    group: 'acme-workers'          // load-balance across group members
});

In a cluster, topic subscribers receive matching messages produced on any node (Clustering).

Fleet-style example

org/acme/machine/m-01/cmd        ← one machine
org/acme/machine/+/cmd           ← all machines in acme
org/acme/#                       ← everything in acme
// control plane
producer.produce(`org/acme/machine/${machineId}/cmd`, { action: 'restart' });

// every agent subscribes to its own command topic
agentConsumer.subscribe(`org/acme/machine/${machineId}/cmd`, handle, {
    mode: 'topic', durable: true, ack: true
});

// a dashboard watches everything
dashboard.subscribe('org/acme/#', render, { mode: 'topic' });

Interaction with exact-match routing

A topic pattern without wildcards behaves exactly like an "any producer" event subscription — the server deduplicates so you never receive the same message twice through both paths. Legacy subscribe(producer, event, …) subscriptions on a topic-shaped event name keep working unchanged alongside pattern subscribers.

Clone this wiki locally