ASP.NET Core  

Performance Optimization Techniques in ASP.NET Core

Introduction

Performance is a critical factor in modern web applications. A slow application leads to poor user experience, higher infrastructure costs, and lost business opportunities. ASP.NET Core is designed for speed, but developers must still apply best practices to ensure optimal performance.

This article explores key performance optimization techniques in ASP.NET Core, with real-time examples to help you implement them effectively.

1. Use Asynchronous Programming

ASP.NET Core supports async/await to handle I/O-bound operations without blocking threads.

Example: Async Database Call

[HttpGet]
public async Task<IActionResult> GetCustomers()
{
    var customers = await _context.Customers.AsNoTracking().ToListAsync();
    return Ok(customers);
}

This allows the server to handle more concurrent requests.

2. Enable Response Caching

Response caching reduces server load by storing responses and serving them for repeated requests.

Example: Configure Response Caching

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCaching();

var app = builder.Build();
app.UseResponseCaching();

app.MapGet("/hello", async context =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(30)
        };
    await context.Response.WriteAsync("Hello World!");
});

app.Run();

This caches responses for 30 seconds, reducing repeated processing.

3. Use AsNoTracking for Read-Only Queries

Entity Framework Core tracks changes by default, which adds overhead. Use AsNoTracking() for read-only queries.

var customers = await _context.Customers.AsNoTracking().ToListAsync();

Improves query performance when updates aren’t needed.

4. Minimize Middleware

Each middleware adds overhead. Only register what you need.

app.UseRouting();
app.UseAuthorization();
// Avoid unnecessary middleware

Keeps the request pipeline lean.

5. Optimize Static File Delivery

Serve static files (CSS, JS, images) efficiently with caching and compression.

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");
    }
});

Reduces repeated downloads of static assets.

6. Use Distributed Caching

For large-scale apps, use distributed caching (e.g., Redis, SQL Server) to store frequently accessed data.

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "SampleApp_";
});

Improves performance by reducing database hits.

7. Optimize Database Queries

  • Use projection (Select) to fetch only required fields.

  • Avoid N+1 queries by using Include.

  • Use indexes in the database.

Example: Projection

var customerNames = await _context.Customers
    .Select(c => c.Name)
    .ToListAsync();

Fetches only names instead of entire customer objects.

8. Enable Response Compression

Compress responses to reduce payload size.

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.MimeTypes = new[] { "text/plain", "application/json" };
});

var app = builder.Build();
app.UseResponseCompression();

Reduces bandwidth usage and speeds up responses.

9. Use Dependency Injection Wisely

Register services with the correct lifetime:

  • Singleton → For shared, thread-safe services.

  • Scoped → For per-request services (like DbContext).

  • Transient → For lightweight, stateless services.

Prevents memory leaks and improves efficiency.

10. Monitor and Profile Performance

Use tools like:

  • Application Insights (Azure)

  • dotTrace (JetBrains)

  • PerfView (Microsoft)

Helps identify bottlenecks and optimize critical paths.

Example

Imagine an E-Commerce Application:

  • Async APIs handle thousands of concurrent users.

  • Response caching speeds up product listing pages.

  • Redis caching reduces database load for frequently accessed items.

  • Compression makes checkout responses faster.

  • Monitoring tools track slow queries and optimize them.

Together, these techniques ensure a fast, scalable, and reliable application.

Conclusion

ASP.NET Core provides powerful features for building high-performance applications. By applying techniques like async programming, caching, compression, and query optimization, you can significantly improve scalability and responsiveness. Continuous monitoring ensures your application stays optimized as it grows.