# Fan-Out (/sdks/nodejs/how-to/fan-out)



## Overview [#overview]

**Fan-out** is the default delivery behavior of KubeMQ Events pub/sub: when subscribers don't join a consumer group, every subscriber gets its own independent copy of each published event. Reach for it whenever several unrelated services need to react to the same occurrence — an order placed, a config change, an audit event — without the publisher knowing or caring who's listening, and without one subscriber's slowness affecting another's delivery.

The mechanism is simply omission: calling `subscribeToEvents` without a `group` option puts that subscription in broadcast mode instead of load-balanced mode. `sendEvent` doesn't change at all — the publisher sends once, and the broker independently pushes a copy to every active subscriber on the channel.

**Gotchas:** fan-out is opt-out by default, so a typo'd or accidentally shared `group` value silently turns broadcast into competing-consumer load-balancing with no error raised. Events are not persisted — a subscriber whose stream hasn't registered yet when `sendEvent` runs misses that event permanently (use Events Store if you need replay). And `sendEvent` resolves as soon as the broker accepts it, not after subscribers process it, so a publisher can outrun subscription setup on a cold start — hence the short delay before publishing in this sample.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Node.js SDK installed (`npm install kubemq-js`)

## Code [#code]

```typescript title="fan-out.ts"
/**
 * Example: Fan-Out Pattern
 *
 * Demonstrates one publisher sending events to multiple independent
 * subscribers. Each subscriber receives a copy of every published event.
 * This is the default behavior for events (no consumer group).
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *
 * Run: npx tsx examples/patterns/fan-out.ts
 */
import { KubeMQClient, createEventMessage } from 'kubemq-js';

async function main(): Promise<void> {
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-patterns-fan-out-client',
  });

  try {
    // Create three independent subscribers — each receives all events.
    const logger = client.subscribeToEvents({
      channel: 'js-patterns.fan-out',
      onEvent: (event) => {
        console.log('[Logger]', new TextDecoder().decode(event.body));
      },
      onError: (err) => {
        console.error('Logger error:', err.message);
      },
    });

    const monitor = client.subscribeToEvents({
      channel: 'js-patterns.fan-out',
      onEvent: (event) => {
        console.log('[Monitor]', new TextDecoder().decode(event.body));
      },
      onError: (err) => {
        console.error('Monitor error:', err.message);
      },
    });

    const alerter = client.subscribeToEvents({
      channel: 'js-patterns.fan-out',
      onEvent: (event) => {
        const body = new TextDecoder().decode(event.body);
        if (body.includes('critical')) {
          console.log('[Alerter] ALERT:', body);
        } else {
          console.log('[Alerter] (ignored non-critical):', body);
        }
      },
      onError: (err) => {
        console.error('Alerter error:', err.message);
      },
    });

    // Publish events — all three subscribers receive each one.
    const events = [
      'cpu_usage=45% status=normal',
      'cpu_usage=92% status=critical',
      'disk_io=120MB/s status=normal',
    ];

    for (const data of events) {
      await client.sendEvent(
        createEventMessage({
          channel: 'js-patterns.fan-out',
          body: data,
          tags: { source: 'system-monitor' },
        }),
      );
    }

    console.log(`\nPublished ${events.length} events to 3 subscribers`);

    await new Promise((resolve) => setTimeout(resolve, 1000));

    logger.cancel();
    monitor.cancel();
    alerter.cancel();
  } finally {
    await client.close();
  }
}

main().catch(console.error);

```

## How It Works [#how-it-works]

* Three separate `subscribeToEvents()` calls — `logger`, `monitor`, `alerter` — all subscribe to the same channel without a `group` option, putting them in fan-out mode where each subscriber independently receives every published event.
* The `alerter` subscriber inspects the event body and reacts differently based on content: it logs a highlighted message for `'critical'` events and ignores others — demonstrating per-subscriber routing logic.
* The 1-second wait after subscribing and before publishing ensures all three gRPC subscription streams are registered on the server, preventing a race where events are published before subscriptions are active.
* Cancelling each handle (`logger.cancel()`, `monitor.cancel()`, `alerter.cancel()`) terminates the three streams independently before the client is closed.

## Related [#related]

* [Pattern overview](/learn/guides/choosing-a-pattern)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Request-Reply](/sdks/nodejs/how-to/request-reply)
* [Work Queue](/sdks/nodejs/how-to/work-queue)
