EF Core Bulk SaveChanges Optimize Entity Framework Saving Performance

Description

The EF BulkSaveChanges extension method execute bulk operations from entries to save.

// Easy to use
context.BulkSaveChanges();

// Easy to customize
context.BulkSaveChanges(options => options.BatchSize = 100);

Try it in EF Core | Try it in EF6

Performance Comparison

Operations 1,000 Entities 2,000 Entities 5,000 Entities
SaveChanges 1,200 ms 2,400 ms 6,000 ms
BulkSaveChanges 150 ms 225 ms 500 ms

Try it in EF Core | Try it in EF6

HINT:

A lot of factors might affect the benchmark time such as index, column type, latency, throttling, etc.

What is supported?

  • All Entity Framework Core Version: EF Core 7, EF Core 6, EF Core 5, EF Core 3
  • All Entity Framework Version: EF6, EF5, EF4
  • All Inheritances (TPC, TPH, TPT)
  • Complex Type/Owned Entity Type
  • Enum
  • Value Converter (EF Core)
  • And more!

Advantages

  • Easy to use
  • Flexible
  • Increase performance
  • Increase application responsivness
  • Reduce database load
  • Reduce database round-trips

FAQ

Why BulkSaveChanges is faster than SaveChanges?

The SaveChanges method makes it quite slow/impossible to handle a scenario that requires to save a lot of entities due to the number of database round-trips required. The SaveChanges perform one database round-trip for every entity to insert. So, if you need to insert 10,000 entities, 10,000 database round-trips will be performed which is INSANELY slow.

The BulkSaveChanges in counterpart requires the minimum number of database round-trips possible. By using Bulk Operations, fewer commands are executed which lead to better performance.

Why BulkSaveChanges update all columns by default (EF6 only)?

The BulkSaveChanges try to combine most commands in a single operation. Updating different columns from an action to another will require generating different SQL and being executed in several database round-trips.

That's still possible to have the same behavior of SaveChanges by disabling the option ForceUpdateUnmodifiedValues:

ctx.BulkSaveChanges(options => options.ForceUpdateUnmodifiedValues = false);

For EF Core, this option is not available. Only columns that have a modification will be saved exactly like SaveChanges.

When should I use BulkSaveChanges over SaveChanges?

Whenever you have more than one entity to save. The BulkSaveChanges is almost as fast as the SaveChanges for one entity, but becomes way faster as the number of entities to save grows.

When should I use BulkSaveChanges over BatchSaveChanges?

BatchSaveChanges become slower and slower in comparisons to BulkSaveChanges when the number of entities to save grows due to the ChangeTracker.

After a few thousands of entities, we recommend using BulkSaveChanges which is a more scalable solution.

Documentation

BatchSaveChanges

Methods
Name Description Example
BulkSaveChanges() Save all changes made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChanges(Action<BulkOperation> bulkOperationFactory) Save all changes made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChanges(bool useEntityFrameworkPropagation) Save all changes made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChanges(bool useEntityFrameworkPropagation, Action<BulkOperation> bulkOperationFactory) Save all changes made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChangesAsync() Save all changes asynchronously made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChangesAsync(Action<BulkOperation> bulkOperationFactory) Save all changes asynchronously made in this context to the underlying database by executing bulk operations. EFCore / EF6
BulkSaveChangesAsync(bool useEntityFrameworkPropagation) Save all changes asynchronously made in this context to the underlying database by executing bulk operations. EF6
BulkSaveChangesAsync(bool useEntityFrameworkPropagation, Action<BulkOperation> bulkOperationFactory) Save all changes asynchronously made in this context to the underlying database by executing bulk operations. EF6
Options

More options can be found here:


Last updated: 2023-03-03
Author:


Contents