# Batch Send (/sdks/nodejs/how-to/queues/batch-send)



## Overview [#overview]

**Batch send** groups several queue messages into one call instead of sending them one at a time. Reach for it when publishing many related items together — importing records, fanning out a set of jobs, replaying a backlog — since sending each message individually pays a full round trip per message, while batching amortizes that cost across the whole set.

It works by building an array of messages with `createQueueMessage(...)`, then passing the array to `client.sendQueueMessagesBatch(messages)` in a single gRPC call. The broker enqueues each message independently and returns a `BatchSendResult` with a `results` array — one entry per message, in the input's order — plus aggregate `successCount`/`failureCount` counters.

**Gotchas:** batching isn't atomic — the broker can accept some messages and reject others in the same call (for example if a channel is full), so always check `r.error` on every result rather than trusting the aggregate counts; a batch is still one bounded request, so it doesn't help continuous, open-ended publishing (use a stream-based send for that); and very large batches raise the size and latency of that single call, so there's a practical ceiling before splitting into multiple batches pays off.

## Prerequisites [#prerequisites]

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

## Code [#code]

```typescript title="batch-send.ts"
/**
 * Example: Batch Message Sending
 *
 * Demonstrates sending multiple queue messages in a single batch operation.
 * The batch result reports which messages succeeded and which failed,
 * allowing partial failure handling.
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *
 * Run: npx tsx examples/queues/batch-send.ts
 */
import { KubeMQClient, createQueueMessage } from 'kubemq-js';

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

  try {
    const messages = [
      createQueueMessage({ channel: 'js-queues.batch-send', body: 'Process image batch-001.zip' }),
      createQueueMessage({ channel: 'js-queues.batch-send', body: 'Process image batch-002.zip' }),
      createQueueMessage({ channel: 'js-queues.batch-send', body: 'Process image batch-003.zip' }),
      createQueueMessage({ channel: 'js-queues.batch-send', body: 'Process image batch-004.zip' }),
      createQueueMessage({ channel: 'js-queues.batch-send', body: 'Process image batch-005.zip' }),
    ];

    const result = await client.sendQueueMessagesBatch(messages);

    console.log(`Batch result: ${result.successCount} succeeded, ${result.failureCount} failed`);

    for (const r of result.results) {
      if (r.error) {
        console.error(`  Message #${r.index} failed:`, r.error.message);
      } else {
        console.log(`  Message #${r.index} sent:`, r.messageId);
      }
    }
  } finally {
    await client.close();
  }
}

main().catch(console.error);

```

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

* `sendQueueMessagesBatch(messages)` sends all 5 messages in a single gRPC call, reducing per-message overhead compared to 5 individual `sendQueueMessage()` calls.
* The returned `BatchSendResult` has `successCount`, `failureCount`, and a `results` array — each entry maps to the original message by `index`.
* The server may accept some messages and reject others (e.g., if a channel is full); always inspect `r.error` for each result to detect partial failures.
* Messages in the batch can target different channels; each `createQueueMessage()` call sets the `channel` independently.

## Related [#related]

* [Pattern overview](/learn/queues/getting-started)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Send & Receive](/sdks/nodejs/tutorials/send-receive)
* [Ack All](/sdks/nodejs/how-to/queues/ack-all)
