Horrible performance using SqlCommand Async methods with large data
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
SqlCommand async methods can improve scalability, but they do not make large result sets intrinsically faster. If performance becomes terrible with big payloads, the real bottleneck is usually query cost, network transfer, buffering, or application-side materialization rather than the fact that the API call is asynchronous.
What Async Actually Buys You
Methods such as ExecuteReaderAsync and ReadAsync help avoid blocking a thread while waiting on I/O. That is valuable in ASP.NET, desktop UI code, and services handling many concurrent requests.
What async does not do is:
- reduce the number of rows returned
- speed up a bad SQL plan
- reduce network payload size
- make large object allocation free
So if a query returns massive data, async may improve responsiveness but still feel slow end-to-end.
A Good Streaming Pattern
When reading large result sets, stream rows instead of buffering everything into memory up front.
SequentialAccess is especially useful when large values such as nvarchar(max) or varbinary(max) are involved.
Large Data Problems Usually Come From One of Four Places
First, the SQL query may be too heavy. If the server spends seconds sorting, scanning, or joining huge tables, async on the client does not matter much.
Second, the payload may simply be too large. Pulling millions of rows or wide blobs over the network is expensive regardless of API style.
Third, the application may materialize everything into memory. Turning a reader into a giant list of objects can dominate runtime and memory usage.
Fourth, there may be too much concurrency. Many simultaneous large async reads can saturate the database, the network, or the application's connection pool.
Fix the Query Before Tuning the API Call
Start with SQL fundamentals:
- return only needed columns
- filter aggressively
- paginate when possible
- verify indexes and execution plans
- avoid
SELECT *on wide tables
If the dataset is conceptually large but users only view one page at a time, fetch one page at a time.
Reducing data volume is usually a larger win than changing synchronous code to asynchronous code.
Avoid Accidental Buffering
Many performance complaints come from code that reads asynchronously but immediately buffers into a large collection.
This is not wrong, but it means the full result still lives in memory. If downstream code can consume rows incrementally, keep the pipeline streaming.
Watch Connection and Thread Usage
Async database APIs work best when they prevent blocked request threads, not when they cause hundreds of oversized queries to run in parallel.
If many large commands run simultaneously, you may see:
- connection pool waits
- more garbage collection pressure
- memory spikes from buffered results
- database-side contention
Bounded concurrency often performs better than maximum concurrency.
Common Pitfalls
The biggest mistake is assuming async should make a huge query fast. It mainly improves how waiting is scheduled, not the cost of the query itself.
Another mistake is reading giant LOB columns without SequentialAccess or other streaming-friendly patterns.
A third issue is fetching far more rows than the application actually needs.
Finally, developers often benchmark only the client method call and ignore server execution plans, network transfer size, and object-allocation costs in the application.
Summary
- '
SqlCommandasync methods improve scalability, not raw database speed.' - Large-result performance problems usually come from query cost, payload size, or buffering.
- Stream results with
ExecuteReaderAsyncandReadAsyncwhen possible. - Use
SequentialAccessfor very large column values. - Reduce data volume before trying to micro-optimize the async API usage.
- Treat async as one part of the solution, not the whole performance strategy.
Related reading
- Host 'xxx.xx.xxx.xxx' is not allowed to connect to this MySQL server
- Host 'xxx.xx.xxx.xxx' is not allowed to connect to this MySQL server
- How are asynchronous DB libraries implemented?
- How are bitmap indexes helpful?
- Horrible redraw performance of the DataGridView on one of my two screens
- How-to run TensorFlow on multiple core and threads
- How do I return the response from an asynchronous call?
- How a thread should close itself in Java?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.