Introduction
A few days ago, one of our clients' accounting officials uploaded an Excel file with student bills and payments — a routine task, done every semester. Except this time, it wasn't routine. The validation API took almost 2 minutes just to process 200 rows, checking each one for duplicates against a database holding over 4 million records. Once validated, hitting "confirm" kicked off the real nightmare: 10+ minutes of waiting, staring at a loading spinner, hoping the connection wouldn't time out before the save finished.
Multiply that by every accounting officer, every semester, every batch of a few thousand students — and you've got a feature that was technically working, but practically unusable at scale.
So I decided to dig in. What I found wasn't one bug — it was a stack of small, very common EF6 mistakes, each one quietly compounding the next: row-by-row duplicate checks hitting the database individually, SaveChanges() called inside a loop, and query patterns that scaled linearly (or worse) with row count instead of staying flat.
After rewriting the pipeline, the same validation that took 2 minutes for 200 rows now handles 5,000 rows in 20 seconds. Saving, which used to take 10+ minutes, now finishes in 1 minute 20 seconds — for a batch 25x larger than before.






