mcpbeat

Migrating Cosmosdb Bulk Executor

microsoft/migrating-cosmosdb-bulk-executor

> Migrates from the deprecated Microsoft.Azure.CosmosDB.BulkExecutor library to the built-in bulk execution support in Microsoft.Azure.Cosmos SDK. Use ONLY when Microsoft.Azure.CosmosDB.BulkExecutor has been flagged as obsolete or deprecated and must be replaced — not for version-bump scenarios where Microsoft.Azure.CosmosDB.BulkExecutor is still supported.

1k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
17
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill migrating-cosmosdb-bulk-executor

The instruction itself

17 sections, as written by the author

Cosmos DB BulkExecutor Migration

Overview

Migrate from the deprecated Microsoft.Azure.CosmosDB.BulkExecutor library to the native bulk execution support in Microsoft.Azure.Cosmos (V3 SDK). The modern SDK supports bulk operations directly through a client option — no separate library is needed. Individual operations are created as tasks and executed concurrently with Task.WhenAll.

Package Reference Changes

Old References (Remove)

<PackageReference Include="Microsoft.Azure.CosmosDB.BulkExecutor" Version="{any}" />

<!-- The BulkExecutor also pulled in the older V2 SDK; remove if no longer needed -->
<PackageReference Include="Microsoft.Azure.DocumentDB" Version="{any}" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="{any}" />

New Reference (Add)

<PackageReference Include="Microsoft.Azure.Cosmos" Version="{latest-stable}" />

Use tools or NuGet to find the latest stable version.

Workflow

Migration Progress:
- [ ] Step 1: Detect BulkExecutor usage
- [ ] Step 2: Update package references
- [ ] Step 3: Replace client initialization
- [ ] Step 4: Convert bulk import operations
- [ ] Step 5: Convert bulk delete operations
- [ ] Step 6: Build and verify

Step 1: Detect BulkExecutor Usage

Scan the project for:

  • using Microsoft.Azure.CosmosDB.BulkExecutor; and sub-namespaces
  • Types: BulkExecutor, IBulkExecutor, BulkImportResponse, BulkDeleteResponse
  • Methods: BulkImportAsync, BulkDeleteAsync
  • DocumentClient usage tied to bulk operations

Step 2: Update Package References

Remove all Microsoft.Azure.CosmosDB.BulkExecutor and legacy Microsoft.Azure.DocumentDB references from the project file. Add Microsoft.Azure.Cosmos if not already present.

Step 3: Replace Client Initialization

Enable bulk mode through CosmosClientOptions:

// Old
var client = new DocumentClient(endpoint, authKey);
var executor = new BulkExecutor(client, collection);
await executor.InitializeAsync();

// New
var client = new CosmosClient(endpoint, authKey, new CosmosClientOptions
{
    AllowBulkExecution = true
});
var container = client.GetContainer(databaseName, containerName);

Step 4: Convert Bulk Import Operations

Replace BulkImportAsync with individual CreateItemAsync tasks executed concurrently:

// Old
BulkImportResponse response = await executor.BulkImportAsync(documents);
Console.WriteLine($"Imported: {response.NumberOfDocumentsImported}");

// New
var tasks = new List<Task<ItemResponse<dynamic>>>();
foreach (var doc in documents)
{
    tasks.Add(container.CreateItemAsync(doc, new PartitionKey(doc.partitionKey)));
}
var responses = await Task.WhenAll(tasks);
Console.WriteLine($"Imported: {responses.Length}");

Track failures by wrapping individual tasks with try/catch or by inspecting each ItemResponse.StatusCode after completion.

Step 5: Convert Bulk Delete Operations

Replace BulkDeleteAsync with individual DeleteItemAsync tasks:

// Old
BulkDeleteResponse response = await executor.BulkDeleteAsync(pkTuples);

// New
var tasks = new List<Task<ItemResponse<dynamic>>>();
foreach (var (id, pk) in itemsToDelete)
{
    tasks.Add(container.DeleteItemAsync<dynamic>(id, new PartitionKey(pk)));
}
await Task.WhenAll(tasks);

Step 6: Build and Verify

  • Build the project:
   dotnet build
  • Verify bulk throughput by running a test batch against a development Cosmos DB container
  • Check that AllowBulkExecution = true is set — without it, operations run sequentially and throughput drops significantly

API Differences

| BulkExecutor (Old) | Cosmos V3 SDK (New) | Notes |

|---------------------|---------------------|-------|

| BulkExecutor class | CosmosClientOptions.AllowBulkExecution = true | No separate executor object needed |

| IBulkExecutor interface | Removed | Use Container methods directly |

| BulkImportAsync(documents) | Task.WhenAll(CreateItemAsync(...)) | One task per document |

| BulkDeleteAsync(pkTuples) | Task.WhenAll(DeleteItemAsync(...)) | One task per item |

| BulkImportResponse | Individual ItemResponse<T> results | Aggregate results manually |

| BulkDeleteResponse | Individual ItemResponse<T> results | Aggregate results manually |

| BulkUpdateAsync | Task.WhenAll(ReplaceItemAsync(...)) | One task per item |

| DocumentClient | CosmosClient | V3 client with connection string or endpoint+key |

Troubleshooting

Low Throughput After Migration

Verify that AllowBulkExecution = true is set on CosmosClientOptions. Without this flag, operations are dispatched individually instead of being batched by the SDK's internal transport layer.

429 (Too Many Requests) Errors

The V3 SDK retries throttled requests automatically. If errors persist, increase the provisioned RU/s on the container or reduce batch concurrency by limiting the number of concurrent tasks.

Partition Key Errors

The V3 SDK requires an explicit PartitionKey on each operation. Extract the partition key value from each document and pass it to CreateItemAsync, DeleteItemAsync, or ReplaceItemAsync.

How to use it

Copy the folder

Take microsoft/migrating-cosmosdb-bulk-executor from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.