| name | migrating-cosmosdb-bulk-executor |
| description | 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.
|
| metadata | {"discovery":"lazy","traits":".NET|CSharp|VisualBasic|DotNetCore"} |
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}" />
<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:
var client = new DocumentClient(endpoint, authKey);
var executor = new BulkExecutor(client, collection);
await executor.InitializeAsync();
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:
BulkImportResponse response = await executor.BulkImportAsync(documents);
Console.WriteLine($"Imported: {response.NumberOfDocumentsImported}");
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:
BulkDeleteResponse response = await executor.BulkDeleteAsync(pkTuples);
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.