# Command Group (/sdks/nodejs/how-to/rpc/command-group)



## Overview [#overview]

A command **consumer group** turns a single command handler into a scalable worker pool: run multiple identical processes subscribed with the same group name, and the broker load-balances each incoming command to exactly one member instead of broadcasting it to all of them. This is how you add capacity to handle a growing command volume — start more processes in the same group — without changing anything on the caller's side.

Every subscriber passes the same `group` alongside `channel` to `subscribeToCommands()`; the broker tracks membership and picks one live member per command. `sendCommand` on the caller side is unaware groups exist — it just awaits a response, which comes back from whichever handler happened to process it via `sendCommandResponse`.

**Gotchas:** group membership is scoped per channel — subscribers on the same channel with *different* group names each get their own full copy of every command (fan-out), which looks like a bug when you expected load-balancing. A slow handler still holds up the caller's timeout, since only one worker is ever picked. And if every member of the group is offline when a command arrives, the send simply fails or times out — commands aren't queued or replayed for a group that has no active listener.

## Prerequisites [#prerequisites]

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

## Code [#code]

```typescript title="command-group.ts"
import { KubeMQClient, createCommand } from 'kubemq-js';

async function main() {
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-rpc-command-group-client',
  });

  try {
    const sub = client.subscribeToCommands({
      channel: 'js-rpc.command-group',
      group: 'handlers',
      onCommand: async (cmd) => {
        console.log('Handler received command:', cmd.id);
        await client.sendCommandResponse({ id: cmd.id, replyChannel: cmd.replyChannel, executed: true });
      },
      onError: (err) => {
        console.error('Sub error:', err.message);
      },
    });

    await new Promise((r) => setTimeout(r, 500));
    const resp = await client.sendCommand(
      createCommand({ channel: 'js-rpc.command-group', body: 'do-work', timeoutInSeconds: 5 }),
    );
    console.log('Command executed:', resp.executed);

    sub.cancel();
  } finally {
    await client.close();
  }
}

main().catch(console.error);

```

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

* `group: 'handlers'` in `subscribeToCommands()` places this handler in the `handlers` consumer group; KubeMQ delivers each command to exactly one group member, enabling horizontal scaling.
* The 500 ms `setTimeout` ensures the subscription is registered on the server before the sender issues the command — without it, the command may arrive before any handler is ready.
* `await client.sendCommandResponse(...)` must be called from the `onCommand` callback before `timeoutInSeconds` elapses; the `async (cmd) => ...` signature ensures the `await` is properly chained.
* To scale out, start multiple processes each subscribing with the same `group` name; KubeMQ round-robins commands across all active members.

## Related [#related]

* [Pattern overview](/learn/rpc/getting-started)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Send Command](/sdks/nodejs/tutorials/command-send)
* [Handle Command](/sdks/nodejs/how-to/rpc/command-handle)
