ASP.NET Core is a high-performance web framework, but the default patterns leave performance on the table. These optimisation patterns are applicable to any ASP.NET Core 3.1 application.
Response compression and caching
Enable response compression (ResponseCompression middleware) for text responses: JSON, HTML, CSS, and JavaScript. Brotli compression reduces response size by 20-26% compared to gzip for typical JSON payloads. Response caching (Cache-Control headers, IMemoryCache, IDistributedCache for Redis) eliminates repeated computation for read-heavy endpoints with tolerable staleness. The combination of compression and caching can reduce server load by 50-70% for read-dominated APIs.
Span and Memory for allocation reduction
System.Span
Minimal API surface for high-throughput endpoints
ASP.NET Core's full MVC pipeline (model binding, action filters, result formatters) adds middleware overhead per request. For highest-throughput endpoints, consider: minimal API endpoints (in .NET 6) or IHttpRequestHandler (in .NET Core 3.x) that bypass MVC overhead, manual JSON parsing with System.Text.Json rather than content negotiation, and returning IActionResult vs ValueTask
Connection and HTTP client reuse
HttpClient should be registered as a singleton or via IHttpClientFactory, never created per request. A new HttpClient per request exhausts the ephemeral port pool under load. IHttpClientFactory manages the lifetime of HttpClientHandler instances, providing connection reuse while allowing handler rotation for DNS changes. For database connections, EF Core's connection pool (managed by the underlying database provider) should be sized appropriately for the expected concurrency.