Skip to main content

Bulk operations

Bulk operations act on many keys in a single call. This article shows you how to put, get, and delete a batch of keys at once, how to read the per-key results, and how to handle partial failure.

Use bulk operations when you have many keys of the same shape to process. They reduce round trips compared with calling the single-key methods in a loop, which matters most against a remote store.

The BulkPutOptions and BulkDeleteOptions types used below live in the Clustron.Zaris.Abstractions namespace. Add using Clustron.Zaris.Abstractions; next to the using Clustron.Zaris.Client; from your client bootstrap.

Put many

Call PutManyAsync<T> with a collection of key-value pairs. A Dictionary<string, T> works directly because it is a sequence of KeyValuePair<string, T>. The method returns one KvResult per item, in the order the items were supplied.

var results = await client.PutManyAsync(new Dictionary<string, string>
{
["user:1"] = "Ali",
["user:2"] = "Sarah",
["user:3"] = "John"
});

if (results.All(r => r.IsSuccess))
{
Console.WriteLine("All items stored.");
}

The signature is:

Task<IReadOnlyList<KvResult>> PutManyAsync<T>(
IEnumerable<KeyValuePair<string, T>> items,
BulkPutOptions? options = null,
CancellationToken ct = default);

All items share the value type T. To store values of different types together, use a batch operation instead.

Get many

Call GetManyAsync<T> with the keys you want. The result is a list of KvResult<T>, one per key, in the same order as the keys you passed. Match each result to its key by position.

var keys = new[] { "user:1", "user:2", "user:3" };
var results = await client.GetManyAsync<string>(keys);

for (int i = 0; i < results.Count; i++)
{
var result = results[i];
if (result.IsSuccess)
{
Console.WriteLine($"{keys[i]} = {result.Value}");
}
else
{
Console.WriteLine($"{keys[i]} failed: {result.Status}");
}
}

A missing key does not fail the whole call. Its entry in the list has IsSuccess of false and Status of KvStatus.NotFound, while the other keys still return their values. Check each result before reading its Value.

Delete many

Call DeleteManyAsync with the keys to remove. Like the other bulk methods, it returns one KvResult per key.

var results = await client.DeleteManyAsync(new[]
{
"user:1",
"user:2",
"user:3"
});

if (results.All(r => r.IsSuccess))
{
Console.WriteLine("All items deleted.");
}

Partial success

Bulk operations are not transactional. Each key is processed independently, so some keys can succeed while others fail. This is why every bulk method returns a list of results rather than a single status: you inspect each entry to find out what happened to that key.

By default the client continues past a failed item and reports it in the results (BulkPutOptions.ContinueOnError and BulkDeleteOptions.ContinueOnError default to true). If you need all-or-nothing semantics, use a transaction instead.

warning

Do not assume a bulk call succeeded because it did not throw. A PutManyAsync that returns normally can still contain per-item failures. Always check the returned results, for example with results.All(r => r.IsSuccess).

Tuning bulk operations

Each bulk method accepts an options record that applies to every item in the call. The most useful settings are:

  • MaxParallelism caps how many items the client processes concurrently. Leave it unset to use the default.
  • ContinueOnError (put and delete) controls whether the client keeps going after an item fails. It defaults to true.
  • IfAbsent and IfMatchVersion (put) apply the same conditional-write checks described in Options to every item.

For example, to store items only when they do not already exist:

await client.PutManyAsync(items, new BulkPutOptions(IfAbsent: true));

Bulk versus basic operations

Choose based on how many keys you touch and whether the round-trip cost matters.

ScenarioRecommended approach
A single keyBasic operations
A few keys, occasionallyBasic operations
Many keys in one logical stepBulk operations
Reducing network round tripsBulk operations
Mixed operation types (put and delete together)Batch operations
All-or-nothing consistencyTransactions

Next steps