Dataverse: ExecuteMultipleRequest vs CreateMultipleRequest Benchmark
This is another benchmark post; this time, we need to compare ExecuteMultipleRequestvs CreateMultipleRequest. For those who don't know ExecuteMultipleRequest allows us to basically mix operations (Create, Update, or Delete) and pass parameters to control if an error is raised during the execution. For CreateMultipleRequest, we only can pass batch create requests (we also have UpdateMultipleRequest) and we need to ensure that the targeted entity/table supports the operation.
To check if the table/entity is supporting the operation, I created the below query that you can run using SQL4CDS:
SELECT a.logicalname, a.objecttypecode FROM entity a JOIN sdkmessagefilter b on a.objecttypecode=b.primaryobjecttypecode
JOIN sdkmessage c on c.sdkmessageid=b.sdkmessageid
WHERE c.name = 'CreateMultiple' AND logicalname LIKE 'ins_%'
Below is the code that I created to benchmark both operations (as usual, I'm using BenchmarkDotNet and Microsoft.PowerPlatform.Dataverse.Client NuGet packages):
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
namespace DataverseClient
{
[MemoryDiagnoser]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[SimpleJob(launchCount: 1, warmupCount: 0)]
public class ExecuteMultipleVsCreateMultiple
{
private IOrganizationService _service;
[GlobalSetup]
public void InitializeService()
{
var builder = Helper.CreateHostBuilder().Build();
var serviceProvider = builder.Services;
_service = serviceProvider.GetRequiredService<ServiceClient>();
}
[Benchmark]
public void ExecuteMultipleRequest()
{
var emr = new ExecuteMultipleRequest
{
Requests = new OrganizationRequestCollection(),
Settings = new ExecuteMultipleSettings
{
ContinueOnError = true,
ReturnResponses = true
}
};
for (var i = 0; i < 10; i++)
{
var create = new Entity("ins_calculate")
{
["ins_name"] = $"ExecuteMultiple {Guid.NewGuid()}",
["ins_qty"] = 1,
["ins_unitprice"] = new Money(100)
};
emr.Requests.Add(new CreateRequest { Target = create });
}
var result = (ExecuteMultipleResponse)_service.Execute(emr);
Console.WriteLine("ExecuteMultipleRequest Responses count: " + result.Responses.Count);
}
[Benchmark]
public void CreateMultiple()
{
var entities = new List<Entity>();
for (var i = 0; i < 10; i++)
{
var create = new Entity("ins_calculate")
{
["ins_name"] = $"CreateMultiple {Guid.NewGuid()}",
["ins_qty"] = 1,
["ins_unitprice"] = new Money(100)
};
entities.Add(create);
}
var cmr = new CreateMultipleRequest { Targets = new EntityCollection(entities) { EntityName = "ins_calculate" } };
var result = (CreateMultipleResponse)_service.Execute(cmr);
Console.WriteLine("CreateMultiple Responses count: " + result.Ids.Length);
}
}
}
Here is the result:
BenchmarkDotNet v0.13.10, Windows 11
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.304
[Host] : .NET 6.0.33 (6.0.3324.36610), X64 RyuJIT AVX2
Job-ABBQKM : .NET 6.0.33 (6.0.3324.36610), X64 RyuJIT AVX2
LaunchCount=1 WarmupCount=0
| Method | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|
| CreateMultiple | 431.2 ms | 8.29 ms | 20.95 ms | 112.29 KB |
| ExecuteMultipleRequest | 713.8 ms | 14.11 ms | 34.09 ms | 148.5 KB |
As for the proof, I screenshot the data created for both operations above:

Based on the above table, we can see that CreateMultipleRequest **** is faster compared to ExecuteMultipleRequest!
Hope you learn something and happy CRM-ing!
Leave a comment
Your comment is sent privately to the author and isn't published on the site.