You deploy an ASP.NET Core API expecting it to be fast.
Then someone reports:
“This endpoint takes 2–3 seconds to respond.”
You check the server.
CPU looks fine.
Memory looks fine.
The database server isn't overloaded.
So where is the time going?
In many cases, the problem isn't ASP.NET Core itself. The delay is hidden somewhere inside the request path — a database round trip, blocking code, an external API, a large response, or application logic.
Here are 5 things I check first when troubleshooting a slow ASP.NET Core API.
1. Check How Many Database Queries One Request Executes
One of the easiest performance problems to miss with EF Core is the N+1 query problem.
For example:
var orders = await dbContext.Orders.ToListAsync();
foreach (var order in orders)
{
var items = await dbContext.OrderItems
.Where(x => x.OrderId == order.Id)
.ToListAsync();
}
If the first query returns 100 orders, the application can end up making 101 database queries.
The code looks reasonable when reading it line by line.
The database sees something very different.
Instead of asking:
"Is this LINQ query correct?"
also ask:
"How many SQL commands does this request actually generate?"
Look at your SQL logs, profiler, APM tool, or database monitoring data.
For read-heavy endpoints, projection can often be a better approach:
var orders = await dbContext.Orders
.Select(o => new OrderDto
{
Id = o.Id,
CustomerName = o.Customer.Name,
Total = o.Items.Sum(i => i.Price * i.Quantity)
})
.ToListAsync();
The important part isn't blindly replacing every query with Select().
It's understanding the SQL and round trips generated by your application.
2. Search Your Codebase for .Result and .Wait()
This is one of the quickest checks I make when an ASP.NET Core API suddenly becomes slow under load.
Look for patterns such as:
var result = service.GetDataAsync().Result;
or:
service.GetDataAsync().Wait();
These calls can block threads while asynchronous work is waiting for I/O.
Under light traffic, you might never notice.
Under higher concurrency, blocked threads can contribute to thread pool starvation and increasing request latency.
Prefer async all the way through the request path:
var result = await service.GetDataAsync();
The important question isn't simply:
"Does this endpoint use async?"
Trace the entire call chain.
Controller → service → repository → database/API
One blocking call buried in that chain can still become a problem.
3. Check Whether Your API Is Waiting for Another API
Your endpoint may look fast from the application code perspective, but your API could actually be spending most of its time waiting for another service.
For example:
Client
↓
ASP.NET Core API
↓
Customer Service
↓
Payment Service
↓
External Provider
If the external provider takes 800 ms, optimizing a few lines of C# won't suddenly make the request 100 ms.
This is where distributed tracing becomes useful.
Instead of only measuring:
Request: 1.4 seconds
you want something closer to:
Total request: 1400 ms
Database: 120 ms
Customer API: 180 ms
Payment API: 850 ms
Serialization: 40 ms
Application logic: 210 ms
Now you have somewhere specific to investigate.
Measure the individual dependencies instead of guessing from the total response time.
4. Look at the Size of Your Response
Sometimes the database query isn't the main problem.
The API simply returns too much data.
For example, an endpoint might return an entire entity when the frontend only needs five fields.
var customers = await dbContext.Customers
.ToListAsync();
If Customer contains dozens of properties and relationships, you're potentially retrieving and serializing much more data than necessary.
A DTO can make the response contract explicit:
var customers = await dbContext.Customers
.Select(x => new CustomerDto
{
Id = x.Id,
Name = x.Name,
Email = x.Email,
Status = x.Status
})
.ToListAsync();
Also check for:
- Large collections
- Missing pagination
- Deeply nested JSON
- Unnecessary navigation properties
- Repeated data in responses
- Expensive serialization
A 5 KB response and a 5 MB response are very different performance problems.
5. Don't Optimize Until You Know Where the Time Goes
This is probably the most important one.
When an API is slow, it's tempting to immediately:
- Add caching
- Increase server resources
- Rewrite LINQ queries
- Change the database
- Add more application servers
- Replace EF Core
- Rewrite the endpoint
Sometimes those changes help.
Sometimes they solve the wrong problem.
Start with measurements.
A simple troubleshooting flow is:
Measure
↓
Trace
↓
Find the bottleneck
↓
Fix it
↓
Measure again
For example, if your endpoint takes 1.8 seconds:
Don't start with:
"Let's optimize the C# code."
Start with:
"Where are those 1.8 seconds being spent?"
That question usually leads to a much better investigation.
What About the Other ASP.NET Core Performance Problems?
These five checks are only a starting point.
Slow ASP.NET Core APIs can also be affected by:
- Inefficient SQL queries
- Missing database indexes
- Poor caching strategies
- Connection management
- Excessive middleware
- Excessive logging
- Inefficient application logic
- Serialization overhead
- Production configuration
- Lack of performance profiling
The important thing is to avoid treating "slow API" as a single problem.
Find the bottleneck first.
Once you know whether the time is being spent in SQL, application code, network calls, serialization, or something else, the optimization becomes much more targeted.
Final takeaway
When an ASP.NET Core API is slow, don't immediately blame the framework.
Start by asking:
- How many database queries does this request execute?
- Is anything blocking an async operation?
- Is the API waiting on another service?
- How much data is being returned?
- Where is the request actually spending its time?
Those five questions can eliminate a lot of guesswork.
If you're troubleshooting a production API, the next step is to look beyond these five checks and examine the other bottlenecks that can affect request latency, database performance, caching, connections, middleware, and application logic.
👉 Read the full guide:
Why ASP.NET Core API Is Slow: 10 Performance Bottlenecks and How to Fix Them
Top comments (0)