Batch Send
Send multiple KubeMQ queue messages in a single batch using the C# SDK for efficient delivery.
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 IEnumerable<QueueMessage>, then passing the collection to client.SendQueueMessagesAsync(messages) in a single gRPC call. The broker assigns each message its own MessageId and persists them independently, reporting any partial failure per message in the result list.
Gotchas: batching isn't atomic — the broker can accept some messages and reject others in the same call, so always check each message's result instead of trusting an overall success; a batch is still one bounded request, so it doesn't help continuous, open-ended publishing (use SendQueueMessagesUpstreamAsync, which streams instead of batching, 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
- KubeMQ server running on
localhost:50000 - C# SDK installed (
dotnet add package KubeMQ.SDK.CSharp)
Code
// KubeMQ .NET SDK — Queues: Batch Send and Receive
//
// This example demonstrates sending and receiving batches of queue messages.
// Batch operations reduce network round trips for high-throughput scenarios.
// Uses QueueDownstreamReceiver.PollAsync for transactional message settlement.
//
// Prerequisites:
// - KubeMQ server running on localhost:50000
// - dotnet run
using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Queues;
using System.Text;
await using var client = new KubeMQClient(new KubeMQClientOptions
{
ClientId = "csharp-queues-batch-send-client",
});
await client.ConnectAsync();
Console.WriteLine("Connected to KubeMQ server");
// Send a batch of messages
var messages = Enumerable.Range(1, 10).Select(i => new QueueMessage
{
Channel = "csharp-queues.batch-send",
Body = Encoding.UTF8.GetBytes($"Batch item #{i}")
}).ToList();
var batchResult = await client.SendQueueMessagesAsync(messages);
Console.WriteLine($"Sent batch of {messages.Count} messages");
// Receive via downstream receiver (supports manual settlement)
await using var receiver = await client.CreateQueueDownstreamReceiverAsync();
var batch = await receiver.PollAsync(new QueuePollRequest
{
Channel = "csharp-queues.batch-send",
MaxMessages = 10,
WaitTimeoutSeconds = 10,
AutoAck = false,
});
Console.WriteLine($"Received {batch.Messages.Count} messages:");
foreach (var msg in batch.Messages)
{
Console.WriteLine($" {Encoding.UTF8.GetString(msg.Body.Span)}");
await msg.AckAsync();
}
Console.WriteLine("Done.");
How It Works
SendQueueMessagesAsync(IEnumerable<QueueMessage>)sends all messages in a single gRPC call, reducing round-trip overhead compared to callingSendQueueMessageAsyncin a loop.- Each message in the batch is independent — the broker assigns a unique
MessageIdto each and persists them individually. A partial failure is reported per-message in the result list. - The downstream receiver is created once and reused for the poll;
AutoAck = falsewith per-messageAckAsync()provides at-least-once delivery semantics. - For very high throughput, consider
SendQueueMessagesUpstreamAsync(stream-based) which avoids the batch size limits of the single-call API.
Related
Was this page helpful?