Skip to content
Rajasekar Su
Go back

Implementing Memory Guard in ASP.NET Core API - Tips for Setting Optimal Thresholds

Why Memory Guard Matters in Real‑World APIs

If you’ve been running ASP.NET Core APIs in production for any length of time, you’ll know that memory issues rarely announce themselves politely. They creep in — a little extra caching here, a big JSON payload there — until one day you’re staring at an IIS recycle or an OutOfMemoryException in the logs.

The .NET garbage collector is excellent, but it’s not a silver bullet. It can’t save you from unbounded caches, large object heap churn, or a DbContext that’s tracking far more entities than you intended. That’s why I like to add a Memory Guard middleware — a lightweight, configurable check that gives me an early warning before things get ugly.

The Middleware I Use

Here’s the exact implementation I’ve been running in ASP.NET Core 8 projects. It’s simple, production‑safe, and easy to tune per environment.

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace WebApi.Middleware;

public class MemoryGuardMiddleware(
    RequestDelegate next,
    ILogger<MemoryGuardMiddleware> logger,
    IConfiguration config)
{
    private readonly int _memoryThresholdMb = config.GetValue("MemoryGuard:ThresholdMB", 512);
    private readonly TimeSpan _sampleInterval = TimeSpan.FromSeconds(
        config.GetValue("MemoryGuard:SampleIntervalSeconds", 30));
    private DateTime _lastSampleTime = DateTime.MinValue;

    public async Task InvokeAsync(HttpContext context)
    {
        var now = DateTime.UtcNow;
        if (now - _lastSampleTime >= _sampleInterval)
        {
            _lastSampleTime = now;
            var processMemoryMb = Process.GetCurrentProcess().PrivateMemorySize64 / (1024 * 1024);

            if (processMemoryMb > _memoryThresholdMb)
            {
                logger.LogWarning(
                    "⚠ High memory usage detected: {ProcessMemoryMB} MB (threshold: {ThresholdMB} MB)",
                    processMemoryMb, _memoryThresholdMb);
            }
        }

        await next(context);
    }
}

appsettings.json:

{
  "MemoryGuard": {
    "ThresholdMB": 1500,
    "SampleIntervalSeconds": 30
  }
}

Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.UseMiddleware<MemoryGuardMiddleware>(); //Add here

app.MapControllers();
app.Run();

How I Pick the Right Thresholds

This is where experience (and a bit of measurement) comes in. The “right” numbers depend on your hosting setup, traffic patterns, and how much headroom you want before IIS or the OS steps in.

ThresholdMB

SampleIntervalSeconds

My Go‑To Starting Point for ASP.NET Core 8 + IIS + EF Core

If I’m spinning up a new API and don’t have baseline data yet, I’ll start with:

Then I’ll watch logs for a week:

Why This Works

This approach gives me:

And most importantly, it’s saved me from more than one “why is the API down?” call at 2 AM.

💡
Pro tip: Pair this with Application Insights alerts and IIS Private Memory limits for a complete safety net. That way, you’re not just reacting to problems — you’re catching them before your users notice.

Summary

Effectively managing memory usage in ASP.NET Core APIs is essential to avoid disruptions such as IIS recycles or OutOfMemoryExceptions. By implementing a configurable Memory Guard middleware, you can receive early alerts about high memory consumption, which helps in maintaining stable performance. Adjusting memory thresholds and sampling intervals according to specific environmental factors allows you to optimize resource management and prevent potential issues before they affect users.


Share this post on:

Previous Post
Understanding the Builder Pattern in C# - A Practical Guide for Developers
Next Post
ASP.NET Core 8 + IIS + EF Core: Proven Memory Management Practices for High‑Performance APIs