Call multiple stored procedures using Async/Await and EntityFramework
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Calling stored procedures asynchronously from Entity Framework is straightforward. Calling several of them correctly is where the design questions start. The main rule is that one DbContext instance cannot execute multiple operations concurrently, so you must choose between sequential awaits on one context or true parallelism with separate contexts.
Sequential Calls on a Single DbContext
If the procedures are part of one logical workflow, the safest option is to run them one after another on the same context. This avoids thread-safety issues and keeps the transaction boundary easier to reason about.
This pattern is still asynchronous. The thread is not blocked while SQL Server works, but the database calls are intentionally serialized.
True Parallelism Requires Separate Contexts
If the procedures are independent and you genuinely want overlap, create separate DbContext instances. The cleanest approach in EF Core is IDbContextFactory.
This is the right way to do concurrent work. Trying the same thing with one shared DbContext usually fails with an exception about a second operation starting before the first completed.
Returning Result Sets from Stored Procedures
Stored procedures that return rows can be materialized through FromSqlRaw on a mapped entity or keyless entity.
The important part is not the syntax. It is the fact that each task owns its own context.
Decide Whether Parallelism Is Worth It
Parallel stored procedure calls are not automatically faster. They increase concurrency on the application side, but they also increase load on the database. If both procedures compete for the same tables, locks, or CPU, running them together may not help.
Use parallelism when the procedures are independent and the database can handle the extra pressure. Otherwise, a simple sequential flow is often the better engineering choice.
Common Pitfalls
The most common mistake is starting multiple async queries on one DbContext. Entity Framework contexts are not thread-safe, and concurrent usage is explicitly unsupported.
Another mistake is using Task.WhenAll because it looks modern, without checking whether the procedures are actually independent. If one procedure must finish before another starts, forcing concurrency only makes the code harder to understand.
Developers also often forget that async improves thread usage, not raw database speed. If SQL Server is the bottleneck, await does not make the stored procedure execute faster. It only prevents your application thread from blocking while it waits.
Finally, be careful with transactions. If you need multiple stored procedures to succeed or fail as one unit, splitting them across separate contexts changes the transaction story. In that case, sequential execution or an explicit distributed design may be more appropriate.
Summary
- Async stored procedure calls in EF are fine, but one
DbContextcannot run multiple operations concurrently. - Use sequential awaits on one context for a single workflow.
- Use separate contexts, often through
IDbContextFactory, for true parallel execution. - '
Task.WhenAllis useful only when the procedures are independent.' - Measure database behavior before assuming parallel stored procedures will improve total latency.

