Background services look harmless… until production. Common mistake Long-running loops No cancellation handling Blocking delays Correct pattern while (!stoppingToken.IsCancellationRequested) { await DoWorkAsync(stoppingToken); await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken); } Why Graceful shutdowns save data and prevent zombie processes.
Category: Asp.Net Core
Why Async Controllers Still Block Threads
Async ≠ non-blocking. The trap public async Task<IActionResult> Get() { var data = _service.GetDataAsync().Result; return Ok(data); } Why it blocks .Result blocks the request thread Can cause thread starvation under load Fix var data = await _service.GetDataAsync();
Environment-Specific Config Overrides
Why it mattersAvoids prod accidents caused by wrong configs.
Minimal APIs with Validation
app.MapPost(“/users”, (User u) => Results.Ok()); Why it mattersLess ceremony, same power.
Use ProblemDetails for API Errors
return Results.Problem(“Invalid input”); Why it mattersStandardized error responses = better clients.
Background Tasks with IHostedService
public class Worker : BackgroundService { protected override Task ExecuteAsync(CancellationToken ct) => Task.CompletedTask; } Why it mattersClean background jobs without hacks.
Use MapGroup for Clean Endpoints
app.MapGroup(“/api/users”) .MapGet(“/”, GetUsers); Why it mattersBetter structure without controllers.
Why Minimal APIs Improve Cold Start
app.MapGet(“/ping”, () => “pong”); Why it mattersLess middleware, faster startup.
Use IHttpClientFactory or Face Socket Exhaustion
Creating HttpClient per request is a silent killer. services.AddHttpClient(); Why this mattersConnection pooling prevents random production outages.
Why BackgroundService Beats Task.Run in APIs
Fire-and-forget tasks die with requests. public class Worker : BackgroundService { protected override async Task ExecuteAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) await DoWorkAsync(ct); } } Why this mattersHosted services respect app lifetime and graceful shutdown.
Use IOptionsSnapshot to Fix Config Reload Issues
Reading config directly causes stale values. public MyService(IOptionsSnapshot<MyConfig> cfg) { _cfg = cfg.Value; } Why this mattersSupports per-request refresh in scoped services.
Why Async Controllers Improve Throughput (Not Speed)
Async doesn’t make code faster — it makes servers scalable. public async Task<IActionResult> Get() { var data = await repo.GetAsync(); return Ok(data); } Why this mattersThreads are freed while waiting → more concurrent requests.
Why IAsyncEnumerable Is a Game-Changer for Data Streaming APIs
Returning large datasets blocks memory.Streaming them changes the entire performance profile. public async IAsyncEnumerable<int> StreamNumbers() { for (int i = 0; i < 1000; i++) { await Task.Delay(10); yield return i; } } Why it works Consumers process data as it arrives Lower memory footprint Faster perceived response times Perfect for: Reporting APIs Log streaming […]
Stop Wasting RAM: The Art of Zero-Allocation C#
How to achieve extreme performance in .NET 9 by mastering Span<T>, Memory<T>, and the Garbage Collector. In the world of cloud-native development, Memory is Money. Every byte you allocate on the Managed Heap is a debt that the Garbage Collector (GC) must eventually collect. The biggest bottleneck in high-throughput .NET applications isn’t typically the CPU’s […]
Is Your Clean Architecture Actually a “Dirty” Mess?
Why modern .NET 9 systems are moving away from rigid layers and embracing the “Vertical Slice” revolution. For the past decade, Clean Architecture (or Onion Architecture) has been the gold standard for .NET developers. We’ve been told to separate our concerns into layers: Domain, Application, Infrastructure, and Web. But as projects grow, we often find […]
The Most Expensive Mistake C# Developers Still Make in 2026
How a single line of Task.Run can turn your high-performance C# application into a production time bomb. For years, C# has been marketed as a “safe” and “high-level” language. Garbage collection, async/await, dependency injection — all designed to protect developers from low-level mistakes. And yet… Some of the most expensive production failures I’ve seen in […]
.NET Core Logs Disappear in Production
Local logs OK, prod empty. Why it happensWrong logging provider configuration. Why it mattersNo observability. Vital fix Explicitly configure providers.
ASP.NET Core APIs Hang Under Load
CPU low, requests hang. Why it happensThread pool starvation. Why it mattersThroughput collapses. Vital fix Avoid blocking calls in async paths.
.NET Core Background Services Block Shutdown
App hangs on exit. Why it happensNo cancellation handling. Why it mattersContainers fail to stop. Smart fixAlways pass CancellationToken.
ASP.NET Core APIs Spike Memory Suddenly
No traffic spike, memory spike. Why it happensObject pooling misuse. Why it mattersUnexpected restarts. Smart fixAvoid pooling large objects.
.NET Core Logging Impacts Performance
Verbose logs slow everything. Why it happensSynchronous logging sinks. Why it mattersThroughput drops silently. Smart fixUse async logging providers.
ASP.NET Core Startup Is Slow
Cold start hurts APIs. Why it happensHeavy dependency injection setup. Why it mattersFirst-request latency. Smart fixLazy-load expensive services. Lazy<MyService>
.NET Core APIs Feel Slow Under Load
Low traffic, bad response. WhySynchronous IO usage. TipPrefer async methods. await stream.ReadAsync(buffer);
ASP.NET Core Memory Grows Slowly
No crash, but RAM increases. WhyScoped services hold references. TipReview service lifetimes.
.NET Core Logs Impact Performance
Logging enabled, speed drops. WhySynchronous log providers. TipUse async logging.
ASP.NET Core Startup Becomes Slower
App works, boot time grows. WhyHeavy work in ConfigureServices. TipDefer non-critical initialization.
.NET Core Memory Grows Without Leaks
GC runs, memory stays high. WhyPinned objects block compaction. TipAvoid pinning unless absolutely required.
ASP.NET Core APIs Return Inconsistent Results
Same request, different responses. WhyMutable singleton services. TipKeep singletons stateless.
.NET Core Apps Restart Too Often in Production
No crashes logged. WhyHealth checks too aggressive. TipAlign health checks with real readiness.
ASP.NET Core Apps Age Poorly Without Errors
Performance drops silently. WhyBackground services accumulate work. TipDesign background tasks with back-pressure.

