High-Performance SQL Server Workloads with C# & SqlBulkCopy
How to eliminate ORM overhead and stream bulk inserts, updates, and merges past 100,000 rows/sec in SQL Server using C# and SqlBulkCopy.
· 9 min read · Intermediate to Advanced
Key takeaways
- Eliminate the performance bottleneck of EF Core row-by-row SaveChanges() loops.
- Leverage IDataReader streaming with SqlBulkCopy to maintain low RAM footprint.
- Implement staged bulk merges with SQL Server Table Valued Parameters (TVPs).
Entity Framework Core is great for day-to-day CRUD. It's not built for looping SaveChanges() over a hundred thousand rows — throughput collapses and memory allocations pile up fast once you push it there.
Reducing ORM Overhead with Bulk Operations
Drop down to raw SqlBulkCopy with a streaming IDataReader over an active SQL connection, and the same dataset moves in batches with a fraction of the overhead a row-by-row ORM write carries.
BulkOperations.Package encapsulates batch streaming behind a clean, fluent C# extension method interface.
It's on NuGet, and it gives you BulkInsertAsync, BulkUpdateAsync, and BulkMergeAsync as drop-in calls across supported .NET versions — no need to hand-roll the SqlBulkCopy plumbing yourself.