# Cancel Subscription (/sdks/nodejs/how-to/events-store/cancel-subscription)



## Overview [#overview]

Every events store subscription opens a long-lived stream to the broker — a background handler that keeps pulling delivered events until you tell it to stop. Calling `sub.cancel()` on the subscription handle is how you release that stream deliberately: shutting down a worker, rotating consumers, or tearing down a process without leaking connections or leaving a dangling stream on the server.

Internally, `cancel()` sends a close signal that unwinds the receive loop and detaches from the broker-side subscription registration; it's safe to call from inside the `onEvent` callback itself, since the SDK finishes the current invocation before stopping the stream.

**Gotchas:** cancelling only stops *this* subscriber — the channel keeps storing every event published afterward, so nothing is lost, and a fresh subscription with `StartFromSequence` or `StartFromFirst` picks up exactly where this one left off. `cancel()` doesn't guarantee the stream has fully torn down the instant it returns, so don't assume zero more callbacks the moment you call it if precise synchronization matters.

## Prerequisites [#prerequisites]

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

## Code [#code]

```typescript title="cancel-subscription.ts"
import { KubeMQClient, EventStoreStartPosition, createEventStoreMessage } from 'kubemq-js';

async function main() {
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-events-store-cancel-subscription-client',
  });

  try {
    let count = 0;
    const sub = client.subscribeToEventsStore({
      channel: 'js-events-store.cancel-subscription',
      startFrom: EventStoreStartPosition.StartFromNew,
      onEvent: (event) => {
        count++;
        console.log(`Received #${count}:`, new TextDecoder().decode(event.body));
        if (count >= 2) sub.cancel();
      },
      onError: (err) => {
        console.error('Error:', err.message);
      },
    });

    for (let i = 1; i <= 5; i++) {
      await client.sendEventStore(
        createEventStoreMessage({
          channel: 'js-events-store.cancel-subscription',
          body: `msg-${i}`,
        }),
      );
    }

    await new Promise((r) => setTimeout(r, 1000));
    console.log('Subscription cancelled after', count, 'messages');
  } finally {
    await client.close();
  }
}

main().catch(console.error);

```

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

* `StartFromNew` subscribes without replaying history — only events published after this subscription is registered are delivered.
* The `onEvent` callback increments a counter and calls `sub.cancel()` when 2 messages have been received, stopping further delivery mid-stream.
* Calling `cancel()` from within the event callback is safe; the SDK completes the current invocation and then stops the stream.
* Events 3, 4, and 5 are still persisted on the server and can be replayed by a future subscriber using `StartFromSequence` or `StartFromFirst`.

## Related [#related]

* [Pattern overview](/learn/events-store/getting-started)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Persistent Pub/Sub](/sdks/nodejs/tutorials/persistent-pubsub)
* [Consumer Group](/sdks/nodejs/how-to/events-store/consumer-group)
