.NET is a powerful framework for building APIs, but as applications scale, performance bottlenecks can emerge. Optimizing API performance is essential for delivering fast, reliable services. This article explores various techniques to improve .NET API performance with detailed examples.

1. Optimize Database Queries

Issue:

A slow API is often caused by inefficient database queries.

Solution:

Example:

public async Task<User> GetUserByIdAsync(int userId)
{
    return await _context.Users
        .AsNoTracking() // Avoids tracking for read-only queries
        .FirstOrDefaultAsync(u => u.Id == userId);
}

2. Use Asynchronous Programming

Issue:

Blocking operations reduce API responsiveness.

Solution:

Example:

[HttpGet("users/{id}")]
public async Task<IActionResult> GetUser(int id)
{
    var user = await _userService.GetUserByIdAsync(id);
    return user == null ? NotFound() : Ok(user);
}

3. Enable Response Caching

Issue:

Repeated requests for the same data can degrade performance.

Solution:

Example:

[HttpGet]
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]
public IActionResult GetWeather()
{
    return Ok(new { Temperature = 25, Condition = "Sunny" });
}

4. Optimize JSON Serialization

Issue:

Serialization can be a performance bottleneck.

Solution:

Example:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = false
};
var json = JsonSerializer.Serialize(data, options);

5. Use Compression

Issue:

Large responses slow down the API.

Solution:

Example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}
 
public void Configure(IApplicationBuilder app)
{
    app.UseResponseCompression();
}

6. Implement Rate Limiting

Issue:

Excessive requests can overload the server.

Solution:

Example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMemoryCache();
    services.Configure<IpRateLimitOptions>(options =>
    {
        options.GeneralRules = new List<RateLimitRule>
        {
            new RateLimitRule
            {
                Endpoint = "*",
                Limit = 100,
                Period = "1m"
            }
        };
    });
}

7. Optimize Middleware Order

Issue:

Incorrect middleware order can impact performance.

Solution:

Correct Order:

app.UseExceptionHandler("/error");
app.UseResponseCompression();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

8. Use Gzip or Brotli Compression

Issue:

Large payloads slow down response times.

Solution:

Example:

services.AddResponseCompression(options =>
{
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

9. Minimize Object Mapping Overhead

Issue:

Excessive object mapping reduces performance.

Solution:

Example:

var config = new MapperConfiguration(cfg => cfg.CreateMap<User, UserDto>());
var mapper = config.CreateMapper();
UserDto userDto = mapper.Map<UserDto>(user);

10. Optimize Logging

Issue:

Excessive logging impacts performance.

Solution:

Example:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

Conclusion

By implementing these performance optimization techniques, you can ensure your .NET API is fast, scalable, and efficient. Always profile and benchmark changes to measure improvements.

Happy coding!