SqlBulkPro 1.0.3

dotnet add package SqlBulkPro --version 1.0.3
                    
NuGet\Install-Package SqlBulkPro -Version 1.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SqlBulkPro" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SqlBulkPro" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="SqlBulkPro" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SqlBulkPro --version 1.0.3
                    
#r "nuget: SqlBulkPro, 1.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SqlBulkPro@1.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SqlBulkPro&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=SqlBulkPro&version=1.0.3
                    
Install as a Cake Tool

SqlBulkPro

NuGet License

High-performance SQL Server bulk operations for .NET 8/9+

SqlBulkPro provides blazing-fast bulk insert, upsert, update, delete, and sync operations for SQL Server using SqlBulkCopy + MERGE. Works seamlessly with EF Core and Dapper/ADO.NET.

Why SqlBulkPro?

  • Measured against EF Core SaveChanges on one SQL Server 2022 container (see benchmarks; about 4× to 10× lower mean time in that run)
  • 🎯 Production-ready with proper locking, transactions, and concurrency handling
  • 🔧 Simple API - single method calls, no complex configuration
  • 🔄 True upsert using SQL Server MERGE (solves EF Core issue #4526 open since 2016)
  • Commercial license — developer $149/year or team $599/year for up to 10 developers. The license key is emailed after purchase. Competitor prices are cited with sources in docs/comparison.md

Quick Start

Installation

dotnet add package SqlBulkPro

EF Core

using SqlBulkPro;

await dbContext.BulkInsertAsync(products);

// Upsert: insert new, update existing
await dbContext.BulkUpsertAsync(products);

// Bulk update
await dbContext.BulkUpdateAsync(products);

// Bulk delete
await dbContext.BulkDeleteAsync(products);

// Keep explicit identity values. The library sets IDENTITY_INSERT on for the write, then off.
await dbContext.BulkInsertAsync(productsWithIds, new BulkOptions { KeepIdentity = true });

Dapper/ADO.NET

using SqlBulkPro;
using Microsoft.Data.SqlClient;

using var connection = new SqlConnection(connectionString);

// Bulk insert with attributes or fluent config
await connection.BulkInsertAsync(products);

// Bulk upsert
await connection.BulkUpsertAsync(products, config => config
    .ToTable("Products", "dbo")
    .HasKey(nameof(Product.Id)));

// Sync, including a transaction overload. DeleteMissingRows is required.
await connection.BulkSyncAsync(products, config => config
    .WithOptions(opt => opt.DeleteMissingRows = true));

Features

Operations

  • ✅ BulkInsert - Fast bulk insertion with identity propagation
  • ✅ BulkUpsert - Insert new rows, update existing (MERGE, or UPDATE then INSERT when Strategy is UpdateInsert)
  • ✅ BulkUpdate - Update matching rows only, including an ADO.NET transaction overload
  • ✅ BulkDelete - Delete matching rows, including an ADO.NET transaction overload
  • ✅ BulkSync - Upsert plus delete of missing rows, on DbContext, DbSet, and SqlConnection

Capabilities

  • 🔑 Composite key support
  • 🆔 Identity value propagation back to entities
  • 🔄 Value converter support (EF Core)
  • 🔒 Proper HOLDLOCK hints to prevent race conditions
  • 📦 Configurable batch sizes
  • ⏱️ Timeout control
  • 🔐 Transaction support (respects ambient transactions)
  • 🎛️ Column filtering (include/exclude specific columns)
  • 🚀 Zero-reflection hot paths (compiled expressions)

Configuration

var options = new BulkOptions
{
    KeyColumns = new List<string> { "ProductCode", "Region" }, // Custom keys
    ColumnsToIgnore = new List<string> { "LastModified" },     // Don't update
    InsertOnlyColumns = new List<string> { "CreatedAt" },      // Insert only
    BatchSize = 10000,                                          // Batch size
    TimeoutSeconds = 60,                                        // Timeout
    UseHoldLock = true,                                         // Prevent races
    ReturnIdentities = true,                                    // Get IDs back
    UpdateOnlyIfChanged = true,                                 // Skip identical rows
    Strategy = MergeStrategy.Merge                              // or UpdateInsert
};

await dbContext.BulkUpsertAsync(products, options);

Performance

One BenchmarkDotNet 0.14.0 run on 9 November 2026. Host: Ubuntu 24.04, 4-core Intel Xeon, 15 GiB RAM, .NET 9.0.22. SQL Server 2022 ran in Docker on that same machine (mcr.microsoft.com/mssql/server:2022-latest). Job: 1 warmup and 3 measured iterations. The speedup column is EF mean / SqlBulkPro mean.

Operation Rows EF Core mean SqlBulkPro mean EF / SqlBulkPro
Insert 1,000 96.96 ms 17.84 ms 5.4
Insert 10,000 517.66 ms 54.06 ms 9.6
Insert 100,000 3,768.89 ms 554.19 ms 6.8
Update vs upsert 1,000 106.31 ms 28.11 ms 3.8
Update vs upsert 10,000 614.58 ms 109.36 ms 5.6
Update vs upsert 100,000 5,226.42 ms 856.17 ms 6.1

Insert compares AddRange + SaveChanges with BulkInsertAsync. Update vs upsert compares UpdateRange + SaveChanges with BulkUpsertAsync after the rows already exist. Standard deviations and the full method notes are in docs/benchmarks.md.

Licensing

SqlBulkPro requires a commercial license for production use.

Trial Mode

  • Limited to 1,000 rows per operation
  • A 14-day in-memory trial check runs outside Development. DOTNET_ENVIRONMENT=Development, ASPNETCORE_ENVIRONMENT=Development, or an attached debugger skips that check. The row cap still applies

License options

The license key is emailed after purchase. Support: dbdavis1990apple@gmail.com

Issuing and the token format are documented in docs/licensing.md.

Activating your license

Use either method. The key is one long string; paste it unchanged.

Environment variable. The library reads SQLBULKPRO_LICENSE_KEY the first time a bulk method runs, unless SqlBulkProLicense.Register was already called. A missing or rejected variable leaves the library in trial mode (1,000 rows, and a console banner). It does not throw.

export SQLBULKPRO_LICENSE_KEY="paste-the-key-here"
$env:SQLBULKPRO_LICENSE_KEY = "paste-the-key-here"

Code. SqlBulkProLicense.Register checks the signature and expiry immediately. An empty, altered, or expired key throws, and a rejected key does not replace one that was already accepted. Call it at startup.

using SqlBulkPro;

var builder = WebApplication.CreateBuilder(args);
SqlBulkProLicense.Register(builder.Configuration["SqlBulkPro:LicenseKey"]!);
var app = builder.Build();
app.Run();

appsettings.json (leave the real key out of source control):

{
  "SqlBulkPro": {
    "LicenseKey": ""
  }
}

User secrets for local development:

dotnet user-secrets set "SqlBulkPro:LicenseKey" "paste-the-key-here"

SqlBulkPro__LicenseKey is the environment-variable form of that configuration entry. It is only used if your startup code passes it to Register. The library itself reads SQLBULKPRO_LICENSE_KEY, not SqlBulkPro__LicenseKey.

If neither Register nor SQLBULKPRO_LICENSE_KEY is set, the library also checks sqlbulkpro.lic next to the application and license.key under the SqlBulkPro folder of the application-data directory. Details are in docs/licensing.md.

Free Tier

For bulk insert only, use the free SqlBulkPro.Lite package (MIT licensed):

dotnet add package SqlBulkPro.Lite

Documentation

Requirements

  • .NET 8.0 or later
  • SQL Server 2016 or later
  • Entity Framework Core 8.0+ (for EF integration)

Support

License

Commercial license required for production use. See LICENSE.txt and EULA.txt.


SqlBulkPro - Built for developers who need production-grade bulk operations without the enterprise price tag.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 0 11/9/2026
1.0.2 0 11/9/2026
1.0.1 0 11/9/2026
1.0.0 0 11/9/2026

1.0.3 adds ADO.NET transaction overloads for update and delete, DbSet.BulkSyncAsync, conditional updates, the UpdateInsert strategy, and catalog-based identity detection.